Conversation
wc_tsip_AesGcmDecrypt only called R_TSIP_AesXXXGcmDecryptFinal when the preceding init/update calls succeeded, unlike its encrypt counterpart. Per the TSIP driver contract, once init or update has been called, final must be called regardless of the prior result, or TSIP is left unable to leave its error state and all subsequent TSIP API calls fail. Call finalFn unconditionally, matching wc_tsip_AesGcmEncrypt.
tsip_Tls13SendFinished re-checked and could grow the output buffer after the caller had already sized it and captured output/input pointers via GetOutputBuffer(). Growing here reallocates ssl->buffers.outputBuffer.buffer without updating the caller's now- stale pointers, so tsip_Tls13BuildMessage() encrypts into a freed buffer while SendBuffered() sends from the new, unwritten one, corrupting the client's Finished message on the wire. Drop the redundant check and rely on the caller's sizing.
tsip_Tls13CertificateVerify() and tsip_Tls13HandleFinished() each advanced inOutIdx by their message content size plus ssl->keys.padSz. That matched the padSz-handling convention in place when this TSIP TLS 1.3 code was written, where each message handler advanced past the record's trailing padSz itself. That convention was later replaced (see "Refactor record padding handling to eliminate middle padding pattern"): ProcessReply now adds padSz exactly once, generically, after it sees a record's content fully consumed, and message handlers are expected to advance the index by content size only. The TSIP handlers were never updated to match, so they now double-count padSz, leaving inOutIdx one padSz past the true record boundary. For CertificateVerify this corrupts the position the next record (Finished) is parsed from, failing the handshake with BUFFER_ERROR (-328) whenever TSIP handles the peer's signature verification. For Finished it corrupts the position of the record after it (NewSessionTicket/application data), so the handshake itself completes but the first subsequent read fails the same way.
It was missing from the project's linked resources, so it never got compiled; wolfssl.rcpc (the e2studio project record) picks up the same addition plus a couple of unrelated toolchain/build-option updates it already carried.
Generated makefiles call BusyBox sed/rm directly, and edits to shared headers like user_settings.h don't trigger incremental rebuilds, so build.bat needed both a fix and a fast path to force-rebuild just the wolfSSL-dependent sources.
Lets the already-flashed target be reset and rerun via rfp-cli without going through the slower erase/program/verify cycle.
Comment whitespace varies between macros (e.g. "/* #define CRYPT_TEST */" vs "/*#define BENCHMARK*/"), which a literal string replace can't handle.
wc_tsip_AesGcmEncrypt() allowed sz == 0 and authInSz == 0 in its own argument validation, but then unconditionally allocated plainBuf (sized sz) and aadBuf (sized authInSz) via XMALLOC and treated a NULL result as an allocation failure. XMALLOC(0, ...) is implementation-defined and may legitimately return NULL, so a valid empty payload or empty AAD could fail depending on allocator behavior rather than on the actual inputs. wc_tsip_AesGcmDecrypt() has the same problem for authInSz == 0 (its sz == 0 case is already rejected by validation, by design, so it never reaches a zero-size allocation there). Skip allocating (and later copying into) plainBuf/aadBuf when their size is 0, and only require them non-NULL in that case, so the zero-length case no longer depends on what the platform's allocator returns for a zero-byte request. Add tsip_aesgcm_zerolen_test() to wolfssl_tsip_unit_test.c covering empty payload with non-empty AAD (encrypt-only, since TSIP decrypt rejects sz == 0 by design), non-empty payload with empty AAD (full encrypt/decrypt round trip), and both empty together.
Adds a brief appendix pointing to the command-line build/flash scripts as an alternative to driving e2studio interactively.
There was a problem hiding this comment.
🟡 Changes recommended
Build-script rebuild handling, X.509 project linkage, and related documentation and contract updates remain unresolved.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
This PR fixes Renesas TSIP TLS 1.3 and AES-GCM issues for the RX72N sample and updates project tooling.
Changes:
- Corrects TLS record accounting, buffer handling, and TSIP GCM finalization.
- Adds zero-length AES-GCM regression coverage.
- Updates project metadata, certificates, scripts, and documentation.
File summaries
| File | Summary |
|---|---|
wolfcrypt/src/port/Renesas/renesas_tsip_util.c |
Fixes TLS 1.3 record accounting and Finished-buffer handling. |
wolfcrypt/src/port/Renesas/renesas_tsip_aes.c |
Fixes GCM finalization and zero-length input handling. |
IDE/Renesas/e2studio/RX72N/EnvisionKit/wolfssl_demo/wolfssl_tsip_unit_test.c |
Adds zero-length AES-GCM regression tests. |
IDE/Renesas/e2studio/RX72N/EnvisionKit/wolfssl_demo/user_settings.h |
Adjusts sample configuration. |
IDE/Renesas/e2studio/RX72N/EnvisionKit/wolfssl_demo/key_data.c |
Regenerates certificate signature data. |
IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/wolfssl/wolfssl.rcpc |
Updates project resources and link order. |
IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/wolfssl/.project |
Updates linked project resources. |
IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/set_demo_mode.ps1 |
Improves demo-mode macro matching. |
IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/README_JP.md |
Documents command-line workflows. |
IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/README_EN.md |
Documents command-line workflows. |
IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/debug_run.bat |
Adds restart-only execution. |
IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/build.bat |
Adds tool-path setup and selective rebuild support. |
Review details
Suppressed comments (6)
IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/README_EN.md:321
- This new command-line appendix leaves the earlier TSIP limitation stating that TLS 1.3
CertificateVerifyis processed in software, whiletsip_Tls13CertificateVerify()now verifies the supported RSA/ECDSA schemes through TSIP and this PR fixes that path. Please update the limitation text so the README does not contradict the implementation and the hardware validation described in the PR.
- `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`.
IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/build.bat:146
- After
cd /d "%BASEDIR%test\HardwareDebug", the generated project metadata lists these objects as flat paths such asHardwareDebug\simple_tcp_client.objandHardwareDebug\key_data.obj(test/test.rcpc:350-396). Prefixing every name withsrc\(andkey_data\) means none of the intended objects is deleted, sobuild.bat wolfsslleaves application objects compiled against the olduser_settings.hdespite claiming to force a rebuild.
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
IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/wolfssl/.project:75
- The corresponding
.projectlink has the same issue as thewolfssl.rcpcentry:src/x509.cis intentionally a no-op when compiled on its own becausessl.calready includes it underWOLFSSL_X509_INCLUDED. Adding this linked resource does not make X.509 code compile and leaves the project claiming the intended fix was applied.
<name>src/x509.c</name>
<type>1</type>
<locationURI>PARENT-7-PROJECT_LOC/src/x509.c</locationURI>
IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/wolfssl/.project:75
- This makes
x509.cvisible in the project and addsx509.objtowolfssl.rcpc, but the checked-in.cproject—the source of the generated makefile according tobuild.bat:85-87—still omits.\src\x509.objfrom its linker order. A fresh e2studio import/build can therefore still produce a library without the newly added object; update the tracked.cprojectlinker list too.
<name>src/x509.c</name>
<type>1</type>
<locationURI>PARENT-7-PROJECT_LOC/src/x509.c</locationURI>
IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/wolfssl/wolfssl.rcpc:20
src/x509.cis not a standalone compilation unit in this tree: it is guarded byWOLFSSL_X509_INCLUDEDandsrc/ssl.cdefines that macro before including it. This new linked resource therefore preprocesses to the warning-only stub and cannot fix a missing X.509 implementation; it only adds a redundant object. Please remove this source entry and the matching link-order entry, or use the project's supported source-splitting approach.
<Path>..\..\..\..\..\..\..\src\x509.c</Path>
IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/wolfssl/wolfssl.rcpc:148
- The checked-in managed-build configuration used by
build.batstill has nosrc\\x509.objin the wolfssl link-order list (Simple/wolfssl/.cproject:74-147), even though this.rcpclink order now includes it. Adding the source only to.rcpcleaves the normal imported/current e2studio project and generated makefile withoutx509.obj, so the library can still omit the file; update/regenerate.cprojectas part of this change.
<Path>Debug\x509.obj</Path>
- Files reviewed: 12/12 changed files
- Comments generated: 2
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
The comment still said inOutIdx lands after "the Finished message and padding" on exit, but the fix in a685fbe made it advance past the message body only, relying on ProcessReply to add padSz once, generically. Left as-is, the stale contract could lead a future change to reintroduce the double-counted padSz this function used to have.
Inside the "if defined FORCE_WOLFSSL_REBUILD (...)" block, %ERRORLEVEL% was expanded once when the block was parsed -- before "%MAKE%" clean had even run -- so it always read the value from before the block (0), letting a failed clean go undetected and the build continue from a partially cleaned tree. Verified by reproducing with a stand-in "make" that fails on "clean": the old check silently proceeded to build "all" regardless; "if errorlevel 1" (tested at the current point, not text-substituted at parse time) plus a literal exit code catch it correctly.
Fixes a PR build test (PRB) failure.
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
Fenrir Automated Review — PR #11479
Scan targets checked: wolfcrypt-port-bugs
Fenrir result: Approved ✅
No new issues found in the changed files.
Advisory only — this automated result does not count as a GitHub approval.
Summary
f10032, f13116
Fixes several Renesas TSIP (Trusted Secure IP) hardware-acceleration bugs found while debugging a TLS 1.3 handshake failure (
BUFFER_ERROR, -328) on the RX72N EnvisionKit sample, plus a couple of small command-line developer-workflow scripts and their documentation.Fixes
Fix TSIP AES-GCM decrypt skipping
finalFnon init/update failure (renesas_tsip_aes.c). OnceR_TSIP_AesXxxGcmDecryptInit/...Updateis called, TSIP requires the matching...Finalcall regardless of the result, or the hardware is left in an error state that fails all subsequent operations; the decrypt path returned early on an init/update failure without ever callingFinal.Fix double
padSzcounting in TSIP TLS 1.3 CertificateVerify/Finished (renesas_tsip_util.c).tsip_Tls13CertificateVerify()andtsip_Tls13HandleFinished()each advanced the read index by their message size plus the record's trailingpadSz, matching the padding-handling convention in place when this TSIP code was written. A later wolfSSL-side refactor centralizedpadSzhandling to be added exactly once, generically, inProcessReply; the TSIP handlers were never updated to match, so they double-countedpadSz, corrupting the read position for the next TLS record. This failed TLS 1.3 handshakes withBUFFER_ERROR(-328) whenever TSIP handled the peer's CertificateVerify signature, and failed the first post-handshake read the same way once CertificateVerify was fixed. Reproduced and fixed on RX72N EnvisionKit hardware (RSA cert / ECC cert, both against a wolfSSL example server).Fix stale output buffer pointer in
tsip_Tls13SendFinished(renesas_tsip_util.c). A buffer-size check re-ranCheckAvailableSize()after the caller had already sized and fetched the output buffer, which could reallocatessl->buffers.outputBuffer.bufferwithout updating the caller's now-staleoutput/inputpointers, so the Finished message could be built into a freed buffer.Fix zero-length payload/AAD handling in TSIP AES-GCM (
renesas_tsip_aes.c).wc_tsip_AesGcmEncrypt()/wc_tsip_AesGcmDecrypt()allowed a zero-length payload/AAD in their own argument validation, but then unconditionally allocated a same-sized scratch buffer viaXMALLOC()and treated aNULLresult as an allocation failure --XMALLOC(0, ...)is implementation-defined and may legitimately returnNULL, so a valid empty payload or AAD could fail depending on allocator behavior rather than the actual inputs. Buffers are now only allocated (and copied into) when their size is non-zero. Addstsip_aesgcm_zerolen_test()towolfssl_tsip_unit_test.c, covering empty payload, empty AAD, and both together; verified passing on RX72N EnvisionKit hardware underTSIP_CRYPT_UNIT_TEST.Link
src/x509.cinto the wolfssl e2studio project (.project,wolfssl.rcpc). It was missing from the project's linked resources, so it never got compiled.Minor / tooling
key_data.c: regenerates the cached CA certificate signature arrays.build.bat: fixes a missingPATHentry for the bundled BusyBox tools the generated makefiles call, and adds awolfsslmode that force-rebuilds just the wolfSSL-dependent sources after editinguser_settings.h.debug_run.bat: adds arestartmode that resets and reruns the already-flashed target without reprogramming it.set_demo_mode.ps1: matches demo-mode macros with a regex instead of a literal string, since comment whitespace varies between macros.README_EN.md/README_JP.md.Testing
TSIP_CRYPT_UNIT_TESTsuite (including the newtsip_aesgcm_zerolen_test) on hardware -- all tests pass.Checklist