diff --git a/IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/README_EN.md b/IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/README_EN.md index decfcbfed82..96fd8f2a668 100644 --- a/IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/README_EN.md +++ b/IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/README_EN.md @@ -307,3 +307,22 @@ The above limitations 1 through 4 are expected to be improved by TSIP from the n # 11. Support For support inquiries and questions, please email support@wolfssl.com. Feel free to reach out to info@wolfssl.jp as well. + +## Appendix: Command-line build & flash (build.bat / debug_run.bat) + +This folder also includes two helper batch files for building and flashing +from the command line instead of driving e2studio interactively. Both wrap +the same Renesas toolchain the IDE uses, and assume the `wolfssl`/`test` +projects and `smc_gen` sources already exist (sections 3-6 above). + +- `build.bat [clean|crypt|bench|TLSClient|wolfssl]` builds the `wolfssl` + and `test` projects. The `wolfssl` mode force-rebuilds just the + wolfSSL-dependent sources after editing `user_settings.h`, without a slow + full `clean`. +- `debug_run.bat [restart]` flashes `test.x` to the board via Renesas Flash + Programmer (rfp-cli) and runs it. `restart` resets and reruns the + already-flashed image without reprogramming it. + +Each script's default paths are tied to one specific e2studio/CCRX install; +see the comments at the top of each file for the environment variables to +override for your setup. diff --git a/IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/README_JP.md b/IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/README_JP.md index 6022c3a620c..9d38df55625 100644 --- a/IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/README_JP.md +++ b/IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/README_JP.md @@ -335,3 +335,20 @@ wolfSSL_CTX_use_certificate_buffer あるいはwolfSSL_CTX_use_certificate_chain ## 11. サポート ご質問・ご要望は、info@wolfssl.jp まで日本語でお知らせください。 + +## 付録: コマンドラインでのビルド・書き込み (build.bat / debug_run.bat) + +e2studioのIDEを対話的に操作する代わりに、コマンドラインからビルド・書き込みを行うための +ヘルパーバッチファイルも本フォルダに含まれています。どちらもIDEと同じRenesasツールチェーンを +呼び出すもので、`wolfssl`/`test`プロジェクトと`smc_gen`のソース(上記3〜6節)が既に生成済みで +あることを前提としています。 + +- `build.bat [clean|crypt|bench|TLSClient|wolfssl]` は`wolfssl`・`test`両プロジェクトを + ビルドします。`wolfssl`引数は、`user_settings.h`編集後にwolfSSL関連のソースだけをフル + クリーンより高速に再ビルドします。 +- `debug_run.bat [restart]` はRenesas Flash Programmer(rfp-cli)経由で`test.x`をボードに + 書き込んで実行します。`restart`引数は、既に書き込み済みのイメージを再書き込みせずに + リセット・再実行します。 + +各スクリプトの既定パスは特定のe2studio/CCRXインストールに紐づいています。環境ごとに上書き +すべき環境変数は各ファイル冒頭のコメントを参照してください。 diff --git a/IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/build.bat b/IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/build.bat index f59df3b73ab..8fb44548aaf 100644 --- a/IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/build.bat +++ b/IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/build.bat @@ -3,16 +3,46 @@ setlocal REM --- These paths are tied to a specific e2studio/CCRX install (plugin version, CCRX REM version, platform ID) and will not exist as-is on a different machine or a different -REM e2studio/CCRX version. Set MAKE/CCRX_BIN/E2_UTILS in the environment before calling -REM build.bat to override the defaults below for your install. --- -if not defined MAKE set MAKE=C:\Renesas\e2_studio\eclipse\plugins\com.renesas.ide.exttools.gnumake.win32.x86_64_4.3.1.v20240909-0854\mk\make.exe -if not defined CCRX_BIN set CCRX_BIN=C:\PROGRA~2\Renesas\RX\3_6_0\bin -if not defined E2_UTILS set E2_UTILS=%USERPROFILE%\.eclipse\com.renesas.platform_1435879475\Utilities\ccrx -set PATH=%CCRX_BIN%;%E2_UTILS%;%PATH% +REM e2studio/CCRX version. Set MAKE/CCRX_BIN/E2_UTILS/E2_BUSYBOX in the environment before +REM calling build.bat to override the defaults below for your install. --- +set USING_DEFAULTS= +if not defined MAKE ( + set MAKE=C:\Renesas\e2_studio\eclipse\plugins\com.renesas.ide.exttools.gnumake.win32.x86_64_4.3.1.v20240909-0854\mk\make.exe + set USING_DEFAULTS=1 +) +if not defined CCRX_BIN ( + set CCRX_BIN=C:\PROGRA~2\Renesas\RX\3_6_0\bin + set USING_DEFAULTS=1 +) +if not defined E2_UTILS ( + set E2_UTILS=%USERPROFILE%\.eclipse\com.renesas.platform_1435879475\Utilities\ccrx + set USING_DEFAULTS=1 +) +REM Generated makefiles call BusyBox "sed"/"rm" directly (not via a shell), so this +REM directory must be on PATH or the linker/clean recipes fail with +REM "process_begin: CreateProcess(NULL, sed ...) failed". +if not defined E2_BUSYBOX ( + set E2_BUSYBOX=C:\Renesas\e2_studio\eclipse\plugins\com.renesas.ide.exttools.busybox.win32.x86_64_1.3.6.v20230615-0931\bin + set USING_DEFAULTS=1 +) +if defined USING_DEFAULTS ( + echo [NOTICE] MAKE/CCRX_BIN/E2_UTILS/E2_BUSYBOX is not set. Using default paths below; + echo these are tied to one specific e2studio/CCRX install and will likely not exist + echo on a different machine or install. Please adjust the paths for your environment + echo by setting these variables before running build.bat. + echo MAKE = %MAKE% + echo CCRX_BIN = %CCRX_BIN% + echo E2_UTILS = %E2_UTILS% + echo E2_BUSYBOX = %E2_BUSYBOX% + echo. + pause +) +set PATH=%CCRX_BIN%;%E2_UTILS%;%E2_BUSYBOX%;%PATH% set BASEDIR=%~dp0 set TARGET=all set MODE= +set FORCE_WOLFSSL_REBUILD= if /i "%1"=="clean" ( set TARGET=clean ) else if /i "%1"=="crypt" ( @@ -21,12 +51,22 @@ if /i "%1"=="clean" ( set MODE=bench ) else if /i "%1"=="TLSClient" ( set MODE=TLSClient +) else if /i "%1"=="wolfssl" ( + set FORCE_WOLFSSL_REBUILD=1 ) else if not "%1"=="" ( echo [ERROR] Unknown argument "%1". - echo Usage: build.bat [clean^|crypt^|bench^|TLSClient] + echo Usage: build.bat [clean^|crypt^|bench^|TLSClient^|wolfssl] echo crypt -^> enables #define CRYPT_TEST in wolfssl_simple_demo.h echo bench -^> enables #define BENCHMARK echo TLSClient -^> enables #define SIMPLE_TLS_TSIP_CLIENT + echo wolfssl -^> force-rebuild files that depend on user_settings.h + echo ^(and other shared wolfSSL headers^) after editing it. + echo The generated makefiles only track each .c's own + echo mtime, not the headers it includes, so plain + echo incremental "build.bat" silently keeps stale objects; + echo "build.bat clean" catches it too but also nukes and + echo recompiles the untouched smc_gen driver/stack code, + echo which takes far longer than the wolfSSL side alone. exit /b 1 ) @@ -64,10 +104,28 @@ if not exist "%BASEDIR%test\src\smc_gen" ( exit /b 1 ) -echo ============================================================ -echo wolfssl library [%TARGET%] -echo ============================================================ -cd /d "%BASEDIR%wolfssl\Debug" +if defined FORCE_WOLFSSL_REBUILD ( + echo ============================================================ + echo wolfssl library [clean rebuild: only 73 objects, stays fast] + echo ============================================================ + cd /d "%BASEDIR%wolfssl\Debug" + "%MAKE%" clean + REM %ERRORLEVEL% would be expanded once when this whole if-block is + REM parsed, before "%MAKE%" clean has even run, always reading as + REM whatever it was beforehand (0) and silently ignoring a failed + REM clean. "if errorlevel 1" tests the real, current errorlevel at + REM this point instead; the exit code below is a literal for the same + REM reason. + if errorlevel 1 ( + echo [ERROR] wolfssl clean failed. + exit /b 1 + ) +) else ( + echo ============================================================ + echo wolfssl library [%TARGET%] + echo ============================================================ + cd /d "%BASEDIR%wolfssl\Debug" +) "%MAKE%" %TARGET% if %ERRORLEVEL% neq 0 ( echo [ERROR] wolfssl build failed. @@ -75,10 +133,32 @@ if %ERRORLEVEL% neq 0 ( ) echo. -echo ============================================================ -echo test application [%TARGET%] -echo ============================================================ -cd /d "%BASEDIR%test\HardwareDebug" +if defined FORCE_WOLFSSL_REBUILD ( + echo ============================================================ + echo test application [selective rebuild: wolfSSL-facing sources only, + echo smc_gen driver/stack objects left untouched] + echo ============================================================ + cd /d "%BASEDIR%test\HardwareDebug" + for %%F in ( + src\client\simple_tcp_client.obj + src\client\simple_tls_tsip_client.obj + src\server\simple_tcp_server.obj + src\server\simple_tls_server.obj + src\key_data\key_data.obj + src\test\benchmark.obj + src\test\test.obj + src\test\wolfssl_dummy.obj + src\test_main.obj + src\wolfssl_tsip_unit_test.obj + ) do ( + if exist "%%F" del /f /q "%%F" + ) +) else ( + echo ============================================================ + echo test application [%TARGET%] + echo ============================================================ + cd /d "%BASEDIR%test\HardwareDebug" +) "%MAKE%" %TARGET% if %ERRORLEVEL% neq 0 ( echo [ERROR] test build failed. diff --git a/IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/debug_run.bat b/IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/debug_run.bat index 581dd280417..2c14e90f321 100644 --- a/IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/debug_run.bat +++ b/IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/debug_run.bat @@ -12,19 +12,69 @@ set TARGET_X=%BASEDIR%test\HardwareDebug\test.x set TARGET_MOT=%BASEDIR%test\HardwareDebug\test.mot set RFP_LOG=%BASEDIR%test_result.log +set MODE=reload +if /i "%1"=="restart" ( + set MODE=restart +) else if not "%1"=="" ( + echo [ERROR] Unknown argument "%1". + echo Usage: debug_run.bat [restart] + echo ^(no arg^) -^> reload: convert+erase+program+verify test.x, then run + echo restart -^> just reset the already-flashed target and run it again, + echo without reprogramming + exit /b 1 +) + REM --- Find the installed Renesas Flash Programmer CLI (version-independent) --- for /d %%d in ("C:\Program Files (x86)\Renesas Electronics\Programming Tools\Renesas Flash Programmer V*") do set RFP_DIR=%%d set RFP_CLI=%RFP_DIR%\rfp-cli.exe -if not exist "%TARGET_X%" ( - echo [ERROR] %TARGET_X% not found. Run build.bat first. - exit /b 1 -) if not exist "%RFP_CLI%" ( echo [ERROR] rfp-cli.exe not found under "C:\Program Files (x86)\Renesas Electronics\Programming Tools\". exit /b 1 ) +if /i "%MODE%"=="restart" goto :restart_mode +goto :reload_mode + +REM --- restart: just reset the already-flashed target, no reprogramming. Kept as +REM top-level (unindented, un-parenthesized) code like the reload path below it -- +REM %RFP_EXIT%/%ERRORLEVEL% are otherwise expanded once at parse time if wrapped in +REM an if-block, before rfp-cli has even run, always reading as stale/empty. --- +:restart_mode +echo [1/1] Restarting target via E2 Lite ^(no reprogramming^)... +echo ============================================================ +del "%RFP_LOG%" > nul 2>&1 +REM Same connection/auth options as the reload path below, but with no hex file and +REM no -e/-p/-v/-a. -sig (read-only device signature check) is required even so: +REM with no operation at all, rfp-cli only connects the emulator, never the target +REM chip, so -run has no reset line to release and prints "No operation" -- -sig +REM forces a real (but safe, flash-untouched) target session so -run actually fires +REM on disconnect. +"%RFP_CLI%" ^ + -device RX72x ^ + -tool e2l ^ + -if fine ^ + -auth id FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ^ + -noquery ^ + -sig -run ^ + -log "%RFP_LOG%" +set RFP_EXIT=%ERRORLEVEL% +echo ============================================================ + +if %RFP_EXIT% neq 0 ( + echo [ERROR] rfp-cli exited with code %RFP_EXIT% +) else ( + echo [DONE] Target restarted -- check Tera Term for UART output. +) + +exit /b %RFP_EXIT% + +:reload_mode +if not exist "%TARGET_X%" ( + echo [ERROR] %TARGET_X% not found. Run build.bat first. + exit /b 1 +) + echo [1/2] Converting ELF ^(test.x^) to Motorola S-record... "%OBJCOPY%" -O srec "%TARGET_X%" "%TARGET_MOT%" if %ERRORLEVEL% neq 0 ( diff --git a/IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/set_demo_mode.ps1 b/IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/set_demo_mode.ps1 index c3138f1014b..925f2678007 100644 --- a/IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/set_demo_mode.ps1 +++ b/IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/set_demo_mode.ps1 @@ -42,9 +42,11 @@ $content = Get-Content -Raw -Path $file # Pass 1: normalize all three macros to the uncommented ("#define X") form, # regardless of their current state, so pass 2's substring replace can't # double-wrap an already-commented line (e.g. match "#define X" inside -# "/*#define X*/"). +# "/*#define X*/"). Whitespace inside the comment markers varies between +# macros (e.g. "/* #define CRYPT_TEST */" vs "/*#define BENCHMARK*/"), so +# match with a regex instead of a literal string. foreach ($m in $macroMap.Values) { - $content = $content.Replace("/*#define $m*/", "#define $m") + $content = $content -replace "/\*\s*#define\s+$m\s*\*/", "#define $m" } # Pass 2: comment out every macro except the selected one. diff --git a/IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/wolfssl/.project b/IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/wolfssl/.project index 068886b4cab..2b6896310fb 100644 --- a/IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/wolfssl/.project +++ b/IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/wolfssl/.project @@ -69,6 +69,11 @@ 1 PARENT-7-PROJECT_LOC/src/wolfio.c + + src/x509.c + 1 + PARENT-7-PROJECT_LOC/src/x509.c + wolfcrypt/port/renesas_common.c 1 diff --git a/IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/wolfssl/wolfssl.rcpc b/IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/wolfssl/wolfssl.rcpc index 6e8f27d1ef6..b2bcc0fcb16 100644 --- a/IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/wolfssl/wolfssl.rcpc +++ b/IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/wolfssl/wolfssl.rcpc @@ -17,6 +17,7 @@ ..\..\..\..\..\..\..\src\tls.c ..\..\..\..\..\..\..\src\tls13.c ..\..\..\..\..\..\..\src\wolfio.c + ..\..\..\..\..\..\..\src\x509.c @@ -89,7 +90,7 @@ R5F572NNHxFB - + @@ -127,7 +128,7 @@ - + Auto @@ -144,6 +145,7 @@ Debug\tls.obj Debug\tls13.obj Debug\wolfio.obj + Debug\x509.obj Debug\renesas_common.obj Debug\renesas_tsip_aes.obj Debug\renesas_tsip_rsa.obj diff --git a/IDE/Renesas/e2studio/RX72N/EnvisionKit/wolfssl_demo/key_data.c b/IDE/Renesas/e2studio/RX72N/EnvisionKit/wolfssl_demo/key_data.c index 8a77c513486..3b5f90ebadf 100644 --- a/IDE/Renesas/e2studio/RX72N/EnvisionKit/wolfssl_demo/key_data.c +++ b/IDE/Renesas/e2studio/RX72N/EnvisionKit/wolfssl_demo/key_data.c @@ -186,64 +186,64 @@ const uint32_t encrypted_user_key_type = const unsigned char ca_ecc_cert_der_sig[] = { - 0x0B, 0x1D, 0x49, 0x40, 0xE8, 0xDA, 0x46, 0xAE, 0x1C, 0x50, - 0xC8, 0x76, 0xF3, 0x57, 0x05, 0x95, 0x89, 0xE1, 0x8B, 0x13, - 0x6B, 0x0F, 0xEB, 0x47, 0x0E, 0x1E, 0x9C, 0x87, 0xBB, 0x07, - 0x6E, 0xE4, 0x6B, 0xDF, 0x5B, 0xEF, 0xA3, 0x2C, 0xD8, 0x07, - 0x91, 0x5B, 0x4E, 0x5B, 0xA1, 0xD0, 0x3E, 0x07, 0x22, 0xAF, - 0x12, 0xF3, 0x0F, 0x62, 0x35, 0x45, 0x82, 0xFC, 0x26, 0x2B, - 0xD1, 0x03, 0x51, 0xAB, 0x35, 0xFE, 0x48, 0x80, 0xC9, 0x68, - 0xA0, 0xE0, 0x54, 0x4A, 0x8F, 0xA7, 0x59, 0xA1, 0xED, 0x57, - 0x3D, 0x9D, 0xC0, 0x6B, 0x22, 0x20, 0xDA, 0x1A, 0xFF, 0xDB, - 0x01, 0x60, 0x59, 0x21, 0x88, 0xD5, 0x5A, 0x40, 0x25, 0x82, - 0xB0, 0x27, 0x54, 0xDC, 0x37, 0x79, 0x70, 0xD1, 0x6C, 0x63, - 0x63, 0xC6, 0x98, 0x63, 0xA9, 0xE6, 0xB7, 0x6C, 0x50, 0xC1, - 0x40, 0xCF, 0xE9, 0x84, 0xC7, 0xB9, 0x8F, 0x7C, 0xC3, 0xE1, - 0xE2, 0x96, 0x67, 0xC6, 0x48, 0x25, 0xD8, 0xB3, 0x40, 0x94, - 0x13, 0xF3, 0x55, 0xF8, 0xC3, 0xEA, 0x39, 0xE1, 0xE9, 0x36, - 0xD1, 0xBE, 0xB2, 0x9C, 0x86, 0xD1, 0x78, 0xE1, 0xC7, 0x67, - 0x3B, 0xD0, 0x10, 0x57, 0x7B, 0x09, 0x33, 0x03, 0x01, 0x8A, - 0xDA, 0x30, 0x1F, 0x74, 0xED, 0x99, 0x8F, 0x93, 0xA2, 0x73, - 0x7B, 0xA6, 0x3A, 0x44, 0x74, 0x9C, 0x5E, 0x19, 0x1B, 0x0B, - 0x63, 0x3A, 0xAF, 0x5C, 0xD5, 0xB4, 0x1C, 0xF0, 0x0B, 0x3F, - 0x15, 0xB3, 0x6B, 0x10, 0x88, 0x93, 0x6C, 0xAB, 0xB4, 0x65, - 0x35, 0xCC, 0x91, 0x9A, 0x19, 0x5D, 0xDF, 0xE0, 0xAC, 0x75, - 0xC3, 0x14, 0x46, 0x2E, 0x7B, 0xF8, 0x73, 0xEB, 0x75, 0xD8, - 0x47, 0xAF, 0x1E, 0x7B, 0x5B, 0xE5, 0x09, 0x01, 0x42, 0x5C, - 0xB3, 0xC6, 0xEB, 0x92, 0xC5, 0x85, 0x6B, 0xD4, 0x22, 0x39, - 0x77, 0x92, 0x13, 0x8A, 0x42, 0x2C + 0x45, 0x72, 0xCC, 0xE1, 0x1E, 0xB8, 0xDE, 0x80, 0x6B, 0x5F, + 0xF9, 0x42, 0xA0, 0xE9, 0x00, 0x87, 0xCD, 0xD2, 0xE6, 0x3F, + 0x95, 0x55, 0xF4, 0xA2, 0xC0, 0xFB, 0x9E, 0xE3, 0x71, 0xBC, + 0xBA, 0x73, 0x83, 0x6B, 0x79, 0xBC, 0x65, 0x3C, 0xB3, 0xC4, + 0x64, 0x40, 0xA2, 0x17, 0x58, 0x39, 0xED, 0xC1, 0x97, 0x91, + 0xD1, 0x29, 0xF2, 0x66, 0x53, 0xD4, 0xFC, 0xEC, 0x60, 0x4A, + 0x4D, 0xD6, 0x93, 0x03, 0xBB, 0x0E, 0xAB, 0x89, 0xEC, 0x6D, + 0xEA, 0xC8, 0x96, 0xF1, 0xF4, 0x34, 0x1D, 0xFA, 0x2E, 0xA8, + 0xBD, 0xBF, 0x0B, 0x93, 0x5C, 0x40, 0x66, 0xE8, 0xA1, 0x63, + 0x80, 0x3B, 0x5B, 0xAE, 0x2C, 0x4F, 0x16, 0x7F, 0x54, 0xC1, + 0x0E, 0x58, 0x94, 0x4D, 0x8D, 0xAF, 0x45, 0x63, 0x55, 0x7E, + 0xCA, 0x8D, 0x71, 0x57, 0x6E, 0x4A, 0x43, 0xD5, 0x65, 0x0E, + 0x3C, 0x02, 0x23, 0xAA, 0x43, 0xA3, 0xEF, 0x43, 0x25, 0x94, + 0x28, 0x6B, 0xE5, 0xE3, 0x8C, 0x75, 0x59, 0x82, 0x84, 0x69, + 0x93, 0xC3, 0x5F, 0x8D, 0x71, 0x2C, 0x83, 0x3A, 0x0B, 0xAF, + 0x3B, 0x08, 0xB9, 0xD7, 0xCF, 0x3A, 0x91, 0x5E, 0x15, 0xD9, + 0x5F, 0xF6, 0xDD, 0x76, 0x8E, 0xA5, 0x6D, 0x6C, 0x2B, 0x68, + 0x7D, 0x47, 0xF5, 0xC2, 0xBF, 0xDE, 0x76, 0x5F, 0x22, 0x85, + 0x9C, 0x17, 0x14, 0x13, 0x10, 0x41, 0x62, 0x2B, 0x85, 0xCC, + 0x9B, 0x34, 0xBF, 0x4D, 0xBF, 0xC2, 0x3C, 0x3F, 0x97, 0xD8, + 0xE8, 0x13, 0x8F, 0x62, 0x7B, 0xBE, 0x4C, 0x86, 0x9B, 0xD2, + 0x08, 0x74, 0xFE, 0xED, 0x67, 0x3F, 0xC3, 0xAD, 0x7F, 0x99, + 0x74, 0x7A, 0x02, 0x33, 0x6E, 0xF0, 0x43, 0x77, 0x0D, 0x5A, + 0x9E, 0x1A, 0x37, 0xE7, 0xD1, 0x12, 0xDD, 0xEE, 0x48, 0xAE, + 0x24, 0x5A, 0x8D, 0x08, 0xDA, 0x43, 0xD7, 0x06, 0xFD, 0xFC, + 0x98, 0x37, 0x8F, 0x1E, 0xF8, 0x2D }; const int sizeof_ca_ecc_cert_sig = sizeof(ca_ecc_cert_der_sig); /* ./ca-cert.der.sign, */ const unsigned char ca_cert_der_sig[] = { - 0x67, 0xBD, 0x28, 0x1E, 0x1A, 0x17, 0xFD, 0x88, 0x03, 0x8B, - 0xA2, 0x5A, 0x65, 0xB3, 0xF2, 0x17, 0x61, 0xE1, 0x7F, 0x9B, - 0xC3, 0x50, 0xEC, 0x55, 0x61, 0x46, 0x0C, 0xC1, 0x2B, 0x9D, - 0x02, 0xDB, 0x0A, 0x36, 0xA1, 0x49, 0x95, 0x42, 0xD1, 0x1A, - 0x75, 0xEC, 0x39, 0xC2, 0x10, 0xC5, 0x9F, 0xDC, 0x8C, 0xBC, - 0x4E, 0x04, 0xC9, 0x5E, 0x52, 0x6B, 0x42, 0xF0, 0x4E, 0x8D, - 0x0D, 0xDD, 0x01, 0x05, 0x14, 0x77, 0x28, 0x75, 0xB6, 0x36, - 0xA8, 0xD1, 0xA9, 0xB4, 0x46, 0xB5, 0xED, 0xD9, 0x10, 0x62, - 0xEC, 0x3B, 0xA5, 0x5B, 0x10, 0xB7, 0xE2, 0xC7, 0x67, 0x4F, - 0x1A, 0x48, 0x9B, 0xAF, 0x31, 0x9D, 0x21, 0xDC, 0x3B, 0x06, - 0xAC, 0x95, 0x78, 0xE6, 0x2D, 0x5F, 0xA8, 0xAD, 0xCC, 0xD2, - 0x4E, 0xF3, 0x4A, 0xC9, 0x7E, 0x4A, 0x28, 0x51, 0x6D, 0xBC, - 0x8D, 0xA5, 0x57, 0x49, 0x32, 0xC0, 0xE2, 0x48, 0x57, 0x8B, - 0x7D, 0x4D, 0x9B, 0x43, 0x99, 0xF0, 0xC0, 0x21, 0xD0, 0xAF, - 0x3D, 0x5B, 0xE0, 0x4F, 0xC2, 0x7C, 0xCF, 0xCC, 0xDB, 0x9A, - 0x79, 0xB6, 0x7E, 0xA0, 0x53, 0xAA, 0x4D, 0x5B, 0xD0, 0x3A, - 0xBA, 0x7F, 0xCC, 0x99, 0xD6, 0x68, 0xD7, 0x14, 0x85, 0xD7, - 0x8E, 0xE0, 0x1A, 0x6E, 0xE7, 0xC1, 0xD5, 0x2B, 0x35, 0x94, - 0x8E, 0xC1, 0x59, 0xC5, 0xAE, 0x48, 0x22, 0x87, 0x36, 0xC1, - 0xA4, 0xD9, 0x58, 0xC1, 0x2A, 0xD6, 0xFE, 0x45, 0x63, 0xCA, - 0x8F, 0x93, 0x86, 0xEC, 0x8D, 0xC2, 0xFD, 0xE3, 0x62, 0xD6, - 0x4C, 0x43, 0xFE, 0x82, 0x4F, 0xC9, 0x9D, 0xA9, 0xD8, 0xE4, - 0x5C, 0x15, 0x6D, 0xDE, 0xF9, 0x3D, 0x76, 0xB7, 0xBA, 0xF7, - 0x1C, 0xFB, 0x90, 0x74, 0xBB, 0x60, 0x93, 0xA4, 0x0C, 0xA4, - 0xFF, 0x41, 0x1C, 0x18, 0x7E, 0xE8, 0xE3, 0x78, 0xF5, 0x52, - 0x98, 0x50, 0xFD, 0xA8, 0x07, 0xAD + 0x66, 0x8F, 0x7B, 0x94, 0xAB, 0x6B, 0xF0, 0x22, 0x8E, 0x69, + 0x51, 0x69, 0x7B, 0x82, 0xC0, 0x4B, 0x68, 0x53, 0x54, 0xC1, + 0x8F, 0x74, 0xD5, 0x24, 0x43, 0x09, 0xE6, 0x93, 0x3C, 0x1C, + 0x05, 0xF4, 0x95, 0xCD, 0xD7, 0x53, 0xBF, 0xE5, 0x9B, 0x50, + 0x76, 0xC1, 0xD8, 0x15, 0x5E, 0x16, 0x44, 0x20, 0x6D, 0x13, + 0x98, 0xD6, 0x51, 0x7A, 0x3F, 0x1A, 0x8E, 0x52, 0x70, 0x23, + 0x6E, 0xC4, 0xC5, 0x7E, 0x58, 0xCF, 0x11, 0x06, 0x43, 0x0C, + 0x47, 0xBA, 0x35, 0x0F, 0xE4, 0xFD, 0xD7, 0x7D, 0x94, 0x6A, + 0xD8, 0x79, 0xAA, 0x0F, 0xF8, 0xCA, 0x66, 0x88, 0x66, 0x0C, + 0xB3, 0x39, 0xC1, 0xE9, 0x00, 0xAD, 0x42, 0xF8, 0xE7, 0x3D, + 0x7A, 0x6F, 0x5A, 0xC8, 0x0F, 0xCE, 0x66, 0xE9, 0xFE, 0xBC, + 0x89, 0xB9, 0x29, 0x3B, 0xD5, 0xA2, 0x67, 0x56, 0x37, 0xD3, + 0xF2, 0xD3, 0x24, 0xB8, 0x94, 0x6A, 0xA9, 0xA3, 0x51, 0x2F, + 0x4B, 0x11, 0xEB, 0x64, 0x28, 0x9E, 0x48, 0x70, 0x47, 0x85, + 0x15, 0x22, 0xE2, 0xC6, 0x89, 0x7E, 0xB9, 0xA7, 0x52, 0x1E, + 0x6C, 0x2D, 0x46, 0x70, 0xE8, 0x01, 0xED, 0x58, 0xD4, 0xC9, + 0xC5, 0xBD, 0x0A, 0x85, 0xD7, 0x33, 0x2C, 0x22, 0xB9, 0x25, + 0xB2, 0xBE, 0x27, 0xA1, 0x9A, 0xF5, 0x15, 0x0E, 0xED, 0xD0, + 0x7F, 0xD4, 0xA7, 0x0E, 0x83, 0x73, 0x2D, 0x86, 0xE7, 0xDE, + 0x2D, 0xAE, 0x30, 0x46, 0xAE, 0xC5, 0x99, 0xAE, 0xA4, 0x61, + 0xB6, 0xC7, 0x63, 0xD1, 0x66, 0xFF, 0xBF, 0xCC, 0x98, 0xCF, + 0x9B, 0xFA, 0xCE, 0xE8, 0xAC, 0xD6, 0x1E, 0xE1, 0xBA, 0xE7, + 0x66, 0x0D, 0xD7, 0x32, 0xBC, 0x62, 0x67, 0x43, 0xFE, 0xE7, + 0xB8, 0xB3, 0xEA, 0x1A, 0x74, 0x82, 0x20, 0x8C, 0xDF, 0xCE, + 0x35, 0xDA, 0xAB, 0x7E, 0x12, 0x8E, 0x4B, 0x39, 0x14, 0x3D, + 0x8A, 0x66, 0x54, 0xB4, 0xA7, 0x3B }; const int sizeof_ca_cert_sig = sizeof(ca_cert_der_sig); /* ./client-cert.der.sign, */ diff --git a/IDE/Renesas/e2studio/RX72N/EnvisionKit/wolfssl_demo/user_settings.h b/IDE/Renesas/e2studio/RX72N/EnvisionKit/wolfssl_demo/user_settings.h index 95515f4c5c0..5d2dddd05ce 100644 --- a/IDE/Renesas/e2studio/RX72N/EnvisionKit/wolfssl_demo/user_settings.h +++ b/IDE/Renesas/e2studio/RX72N/EnvisionKit/wolfssl_demo/user_settings.h @@ -276,7 +276,6 @@ *-----------------------------------------------------------------------*/ #define CUSTOM_RAND_GENERATE_BLOCK wc_tsip_GenerateRandBlock #else - #define OPENSSL_EXTRA #define WOLFSSL_GENSEED_FORTEST /* Warning: define your own seed gen */ #if !defined(min) #define min(data1, data2) _builtin_min(data1, data2) diff --git a/IDE/Renesas/e2studio/RX72N/EnvisionKit/wolfssl_demo/wolfssl_tsip_unit_test.c b/IDE/Renesas/e2studio/RX72N/EnvisionKit/wolfssl_demo/wolfssl_tsip_unit_test.c index c84c01aac9e..fc21332fd7e 100644 --- a/IDE/Renesas/e2studio/RX72N/EnvisionKit/wolfssl_demo/wolfssl_tsip_unit_test.c +++ b/IDE/Renesas/e2studio/RX72N/EnvisionKit/wolfssl_demo/wolfssl_tsip_unit_test.c @@ -982,6 +982,122 @@ static void tskAes128_Gcm_Test(void *pvParam) vTaskDelete(NULL); } #endif /* FREERTOS */ + +/* Regression test for zero-length payload/AAD handling in + * wc_tsip_AesGcmEncrypt()/wc_tsip_AesGcmDecrypt() (renesas_tsip_aes.c): a + * payload or AAD length of 0 is a legal AES-GCM input, but those functions + * used to XMALLOC(0, ...) a same-sized scratch buffer for it and treat a + * NULL result as an allocation failure -- whether that happened depended on + * the platform allocator's handling of a zero-byte request, not on the + * actual GCM inputs. + */ +static int tsip_aesgcm_zerolen_test(int prnt, int devId) +{ + Aes enc[1]; + Aes dec[1]; + + WOLFSSL_SMALL_STACK_STATIC const byte key[] = + { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + }; + + WOLFSSL_SMALL_STACK_STATIC const byte iv[] = + { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b + }; + + WOLFSSL_SMALL_STACK_STATIC const byte aad[] = + { + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f + }; + + WOLFSSL_SMALL_STACK_STATIC const byte plain[] = + { + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f + }; + + byte resultT[WC_AES_BLOCK_SIZE]; + byte resultC[sizeof(plain) + WC_AES_BLOCK_SIZE]; + byte resultP[sizeof(plain) + WC_AES_BLOCK_SIZE]; + int ret; + + if (prnt) { + printf(" tsip_aesgcm_zerolen_test() "); + } + + if (wc_AesInit(enc, NULL, devId) != 0) { + ret = -1; + goto out; + } + if (wc_AesInit(dec, NULL, devId) != 0) { + ret = -2; + goto out; + } + wc_AesGcmSetKey(enc, key, sizeof(key)); + wc_AesGcmSetKey(dec, key, sizeof(key)); + + /* (a) empty payload, non-empty AAD -- used to fail because plainBuf was + * XMALLOC(0, ...)'d in wc_tsip_AesGcmEncrypt(). TSIP rejects a + * zero-length decrypt by design (unrelated to this fix), so this case + * is encrypt-only. */ + XMEMSET(resultT, 0, sizeof(resultT)); + ret = wc_AesGcmEncrypt(enc, NULL, NULL, 0, iv, sizeof(iv), + resultT, sizeof(resultT), aad, sizeof(aad)); + if (ret != 0) { + ret = -3; + goto out; + } + + /* (b) non-empty payload, empty AAD -- used to fail the same way via + * aadBuf, in both wc_tsip_AesGcmEncrypt() and wc_tsip_AesGcmDecrypt(). + * A non-zero sz decrypt is fully supported by TSIP, so round-trip + * through both. */ + XMEMSET(resultT, 0, sizeof(resultT)); + XMEMSET(resultC, 0, sizeof(resultC)); + XMEMSET(resultP, 0, sizeof(resultP)); + ret = wc_AesGcmEncrypt(enc, resultC, plain, sizeof(plain), iv, sizeof(iv), + resultT, sizeof(resultT), NULL, 0); + if (ret != 0) { + ret = -4; + goto out; + } + ret = wc_AesGcmDecrypt(dec, resultP, resultC, sizeof(plain), iv, + sizeof(iv), resultT, sizeof(resultT), NULL, 0); + if (ret != 0) { + ret = -5; + goto out; + } + if (XMEMCMP(plain, resultP, sizeof(plain))) { + ret = -6; + goto out; + } + + /* (c) empty payload and empty AAD together -- both skip paths in + * wc_tsip_AesGcmEncrypt() exercised in the same call. */ + XMEMSET(resultT, 0, sizeof(resultT)); + ret = wc_AesGcmEncrypt(enc, NULL, NULL, 0, iv, sizeof(iv), + resultT, sizeof(resultT), NULL, 0); + if (ret != 0) { + ret = -7; + goto out; + } + + ret = 0; + + out: + wc_AesFree(enc); + wc_AesFree(dec); + + if (prnt) { + RESULT_STR(ret) + } + + return ret; +} #endif @@ -1754,6 +1870,14 @@ int tsip_crypt_test(void) if (ret == 0) ret = tsip_aesgcm256_test(1, devId); } + #if defined(WOLFSSL_AES_128) + if (ret == 0) { + Clr_CallbackCtx(&userContext); + ret = TSIP_AesKeyGeneration(&userContext, 16); + if (ret == 0) + ret = tsip_aesgcm_zerolen_test(1, devId); + } + #endif #endif #if defined(WOLFSSL_AES_COUNTER) &&\ diff --git a/wolfcrypt/src/port/Renesas/renesas_tsip_aes.c b/wolfcrypt/src/port/Renesas/renesas_tsip_aes.c index 9d3774bbfa1..881a6748723 100644 --- a/wolfcrypt/src/port/Renesas/renesas_tsip_aes.c +++ b/wolfcrypt/src/port/Renesas/renesas_tsip_aes.c @@ -853,24 +853,32 @@ int wc_tsip_AesGcmEncrypt( /* allocate buffers for plaintext, ciphertext, authTag and aad to make * sure those buffers 32bit aligned as TSIP requests. + * sz/authInSz may legally be 0 (empty payload/AAD); XMALLOC(0, ...) + * is implementation-defined and may return NULL, so skip allocating + * (and later copying into) a buffer whose size is 0 rather than + * treating that NULL as an allocation failure. */ - plainBuf = XMALLOC(sz, aes->heap, DYNAMIC_TYPE_AES); + if (sz != 0) + plainBuf = XMALLOC(sz, aes->heap, DYNAMIC_TYPE_AES); cipherBuf = XMALLOC(cipherBufSz, aes->heap, DYNAMIC_TYPE_AES); aTagBuf = XMALLOC(TSIP_AES_GCM_AUTH_TAG_SIZE, aes->heap, DYNAMIC_TYPE_AES); - aadBuf = XMALLOC(authInSz, aes->heap, DYNAMIC_TYPE_AES); + if (authInSz != 0) + aadBuf = XMALLOC(authInSz, aes->heap, DYNAMIC_TYPE_AES); - if (plainBuf == NULL || cipherBuf == NULL || aTagBuf == NULL || - aadBuf == NULL ) { + if ((sz != 0 && plainBuf == NULL) || cipherBuf == NULL || + aTagBuf == NULL || (authInSz != 0 && aadBuf == NULL)) { WOLFSSL_MSG("wc_tsip_AesGcmEncrypt: buffer allocation failed"); ret = -1; } if (ret == 0) { - XMEMCPY(plainBuf, in, sz); + if (sz != 0) + XMEMCPY(plainBuf, in, sz); ForceZero(cipherBuf, cipherBufSz); ForceZero(authTag, authTagSz); - XMEMCPY(aadBuf, authIn, authInSz); + if (authInSz != 0) + XMEMCPY(aadBuf, authIn, authInSz); } #if defined(WOLFSSL_RENESAS_TSIP_TLS) @@ -935,8 +943,7 @@ int wc_tsip_AesGcmEncrypt( /* Once R_TSIP_AesxxxGcmEncryptInit or R_TSIP_AesxxxEncryptUpdate is * called, R_TSIP_AesxxxGcmEncryptFinal must be called regardless of - * the result of the previous call. Otherwise, TSIP can not come out - * from its error state and all the trailing APIs will fail. + * the result of the previous call. */ dataLen = 0; err = finalFn(&hdl, @@ -945,8 +952,10 @@ int wc_tsip_AesGcmEncrypt( aTagBuf); /* aad of 16 bytes will be output */ if (err == TSIP_SUCCESS) { - /* copy encrypted data to out */ - XMEMCPY(out, cipherBuf, sz); + /* copy encrypted data to out (sz may be 0, and out may then + * legally be NULL per the argument validation above) */ + if (sz != 0) + XMEMCPY(out, cipherBuf, sz); /* copy auth tag to caller's buffer */ XMEMCPY((void*)authTag, (void*)aTagBuf, @@ -1052,15 +1061,22 @@ int wc_tsip_AesGcmDecrypt( /* allocate buffers for plaintext, cipher-text, authTag and AAD. * TSIP requests those buffers 32bit aligned. + * authInSz may legally be 0 (no AAD); XMALLOC(0, ...) is + * implementation-defined and may return NULL, so skip allocating + * (and later copying into) aadBuf when there is no AAD, rather than + * treating that NULL as an allocation failure. (sz == 0 is already + * rejected by the argument validation above, so cipherBuf/plainBuf + * are never zero-size here.) */ cipherBuf = XMALLOC(sz, aes->heap, DYNAMIC_TYPE_AES); plainBuf = XMALLOC(plainBufSz, aes->heap, DYNAMIC_TYPE_AES); aTagBuf = XMALLOC(TSIP_AES_GCM_AUTH_TAG_SIZE, aes->heap, DYNAMIC_TYPE_AES); - aadBuf = XMALLOC(authInSz, aes->heap, DYNAMIC_TYPE_AES); + if (authInSz != 0) + aadBuf = XMALLOC(authInSz, aes->heap, DYNAMIC_TYPE_AES); if (plainBuf == NULL || cipherBuf == NULL || aTagBuf == NULL || - aadBuf == NULL) { + (authInSz != 0 && aadBuf == NULL)) { ret = -1; } @@ -1069,7 +1085,8 @@ int wc_tsip_AesGcmDecrypt( XMEMCPY(cipherBuf, in, sz); ForceZero(aTagBuf, TSIP_AES_GCM_AUTH_TAG_SIZE); XMEMCPY(aTagBuf,authTag,min(authTagSz, TSIP_AES_GCM_AUTH_TAG_SIZE)); - XMEMCPY(aadBuf, authIn, authInSz); + if (authInSz != 0) + XMEMCPY(aadBuf, authIn, authInSz); } #if defined(WOLFSSL_RENESAS_TSIP_TLS) @@ -1133,14 +1150,19 @@ int wc_tsip_AesGcmDecrypt( WOLFSSL_MSG("R_TSIP_AesXXXGcmDecryptUpdate: failed in decrypt"); ret = -1; } - if (err == TSIP_SUCCESS) { - dataLen = 0; - err = finalFn(&hdl, - plainBuf + (sz / WC_AES_BLOCK_SIZE) * WC_AES_BLOCK_SIZE, - &dataLen, - aTagBuf, - min(16, authTagSz)); /* TSIP accepts upto 16 byte */ - } + + /* Once R_TSIP_AesxxxGcmDecryptInit or R_TSIP_AesxxxGcmDecryptUpdate + * is called, R_TSIP_AesxxxGcmDecryptFinal must be called regardless + * of the result of the previous call. Otherwise, TSIP can not come + * out from its error state and all the trailing APIs will fail. + */ + dataLen = 0; + err = finalFn(&hdl, + plainBuf + (sz / WC_AES_BLOCK_SIZE) * WC_AES_BLOCK_SIZE, + &dataLen, + aTagBuf, + min(16, authTagSz)); /* TSIP accepts upto 16 byte */ + if (err == TSIP_SUCCESS) { /* copy plain data to out */ XMEMCPY(out, plainBuf, sz); diff --git a/wolfcrypt/src/port/Renesas/renesas_tsip_util.c b/wolfcrypt/src/port/Renesas/renesas_tsip_util.c index 3f687504b41..609eab3341e 100644 --- a/wolfcrypt/src/port/Renesas/renesas_tsip_util.c +++ b/wolfcrypt/src/port/Renesas/renesas_tsip_util.c @@ -1268,7 +1268,11 @@ static int tsipTls13VerifyHandshake(struct WOLFSSL* ssl, * ssl WOLFSSL object * input the buffer holding decrypted finished message, type and padding * inOutIdx On entry, the index into the message content of Finished. - * On exit, the index of byte after the Finished message and padding. + * On exit, the index of byte after the Finished message body. + * padSz (type and padding) is added once by the caller + * (ProcessReply, internal.c) after it sees the record's content + * fully consumed -- this function must not add it too, or the + * index ends up one padSz past the true record boundary. * size Length of message content(excluding type and padding) * totalSz Length in the record header. means message + type + pad. * return 0, on success, others on failure. @@ -1293,8 +1297,15 @@ int tsip_Tls13HandleFinished( } if (ret == 0) { - /* Force input exhaustion at ProcessReply by consuming padSz. */ - *inOutIdx += size + ssl->keys.padSz; + /* Advance past the Finished body only, matching the software + * DoTls13Finished path (`*inOutIdx += size;`, tls13.c). padSz (AEAD + * tag + inner content type) is added once, generically, by + * ProcessReply once it sees the record's content fully consumed + * (internal.c) -- adding it here too double-counts it and pushes + * inOutIdx past the true record boundary, corrupting the position + * the next record (NewSessionTicket/application data) is parsed + * from. Same bug/fix as tsip_Tls13CertificateVerify above. */ + *inOutIdx += size; ssl->options.serverState = SERVER_FINISHED_COMPLETE; } @@ -1433,12 +1444,13 @@ int tsip_Tls13SendFinished( ret = tsip_Tls13GetHmacMessages(ssl, (byte*)&input[headerSz]); } - if (ret == 0) { - recordSz = WC_MAX_DIGEST_SIZE + DTLS_HANDSHAKE_HEADER_SZ + MAX_MSG_EXTRA; - /* check for available size */ - ret = CheckAvailableSize(ssl, recordSz); - recordSz = 0; - } + /* Do not re-check/grow the output buffer here: the caller + * (SendTls13Finished) already sized it with CheckAvailableSize() before + * fetching `output`/`input` via GetOutputBuffer(). A grow here would + * reallocate ssl->buffers.outputBuffer.buffer without updating the + * caller's now-stale output/input pointers, so tsip_Tls13BuildMessage() + * below would encrypt into a freed buffer while SendBuffered() sends + * from the new, unwritten one. */ if (ret == 0) { recordSz = tsip_Tls13BuildMessage(ssl, @@ -1576,8 +1588,13 @@ int tsip_Tls13CertificateVerify(struct WOLFSSL* ssl, if (err == TSIP_SUCCESS) { + /* Advance past the CertificateVerify body only. padSz (AEAD + * tag + inner content type) is added once, generically, by + * ProcessReply once it sees the record's content fully + * consumed -- adding it here too double-counts it and pushes + * inOutIdx past the true record boundary, corrupting the + * position the next record (Finished) is parsed from. */ *inOutIdx += totalSz; - *inOutIdx += ssl->keys.padSz; ssl->options.peerAuthGood = 1; ssl->options.havePeerVerify = 1; #if !defined(NO_WOLFSSL_CLIENT)