Skip to content

TSIP TLS 1.3 / AES-GCM fixes for the RX72N sample - #11479

Open
miyazakh wants to merge 14 commits into
wolfSSL:masterfrom
miyazakh:f10032_tsipgcm
Open

miyazakh wants to merge 14 commits into
wolfSSL:masterfrom
miyazakh:f10032_tsipgcm

Conversation

@miyazakh

Copy link
Copy Markdown
Contributor

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 finalFn on init/update failure (renesas_tsip_aes.c). Once R_TSIP_AesXxxGcmDecryptInit/...Update is called, TSIP requires the matching ...Final call 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 calling Final.

  • Fix double padSz counting in TSIP TLS 1.3 CertificateVerify/Finished (renesas_tsip_util.c). tsip_Tls13CertificateVerify() and tsip_Tls13HandleFinished() each advanced the read index by their message size plus the record's trailing padSz, matching the padding-handling convention in place when this TSIP code was written. A later wolfSSL-side refactor centralized padSz handling to be added exactly once, generically, in ProcessReply; the TSIP handlers were never updated to match, so they double-counted padSz, corrupting the read position for the next TLS record. This failed TLS 1.3 handshakes with BUFFER_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-ran CheckAvailableSize() after the caller had already sized and fetched the output buffer, which could reallocate ssl->buffers.outputBuffer.buffer without updating the caller's now-stale output/input pointers, 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 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 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. Adds tsip_aesgcm_zerolen_test() to wolfssl_tsip_unit_test.c, covering empty payload, empty AAD, and both together; verified passing on RX72N EnvisionKit hardware under TSIP_CRYPT_UNIT_TEST.

  • Link src/x509.c into 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 missing PATH entry for the bundled BusyBox tools the generated makefiles call, and adds a wolfssl mode that force-rebuilds just the wolfSSL-dependent sources after editing user_settings.h.
  • debug_run.bat: adds a restart mode 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.
  • Briefly documents both scripts in README_EN.md/README_JP.md.

Testing

  • Reproduced and fixed the TLS 1.3 handshake failure (RSA cert, TSIP-accelerated CertificateVerify) and the subsequent post-handshake read failure (ECC cert) on RX72N EnvisionKit hardware against a wolfSSL example server; both now complete successfully.
  • Ran the full TSIP_CRYPT_UNIT_TEST suite (including the new tsip_aesgcm_zerolen_test) on hardware -- all tests pass.

Checklist

  • added tests
  • updated/added doxygen
  • updated appropriate READMEs
  • Updated manual and documentation

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.
Copilot AI lite review requested due to automatic review settings September 17, 2026 03:31
@miyazakh miyazakh self-assigned this Sep 17, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 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 CertificateVerify is processed in software, while tsip_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 as HardwareDebug\simple_tcp_client.obj and HardwareDebug\key_data.obj (test/test.rcpc:350-396). Prefixing every name with src\ (and key_data\) means none of the intended objects is deleted, so build.bat wolfssl leaves application objects compiled against the old user_settings.h despite 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 .project link has the same issue as the wolfssl.rcpc entry: src/x509.c is intentionally a no-op when compiled on its own because ssl.c already includes it under WOLFSSL_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.c visible in the project and adds x509.obj to wolfssl.rcpc, but the checked-in .cproject—the source of the generated makefile according to build.bat:85-87—still omits .\src\x509.obj from its linker order. A fresh e2studio import/build can therefore still produce a library without the newly added object; update the tracked .cproject linker 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.c is not a standalone compilation unit in this tree: it is guarded by WOLFSSL_X509_INCLUDED and src/ssl.c defines 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.bat still has no src\\x509.obj in the wolfssl link-order list (Simple/wolfssl/.cproject:74-147), even though this .rcpc link order now includes it. Adding the source only to .rcpc leaves the normal imported/current e2studio project and generated makefile without x509.obj, so the library can still omit the file; update/regenerate .cproject as 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.

Comment thread IDE/Renesas/e2studio/RX72N/EnvisionKit/Simple/build.bat Outdated
Comment thread wolfcrypt/src/port/Renesas/renesas_tsip_util.c
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 wolfSSL-Fenrir-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@miyazakh miyazakh assigned wolfSSL-Bot and unassigned miyazakh Sep 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants