CVE-2026-13758 Overview
CVE-2026-13758 is a timing side-channel vulnerability in the CryptX Perl module affecting versions before 0.088_001. The flaw exists in the streaming decrypt_done($tag) code path, which compares Authenticated Encryption with Associated Data (AEAD) authentication tags using memNE (a memcmp() != 0 wrapper). Because memcmp short-circuits on the first differing byte, its execution time leaks information about how many leading bytes matched. All five supported AEAD modes are affected: GCM, CCM, ChaCha20Poly1305, EAX, and OCB. The one-shot *_decrypt_verify helpers are not affected because libtomcrypt performs the tag comparison in constant time.
Critical Impact
An attacker capable of submitting many candidate tags for the same nonce, ciphertext, and associated data while measuring response time can recover an expected authentication tag byte by byte, enabling message forgery against affected AEAD streams.
Affected Products
- CryptX for Perl versions prior to 0.088_001
- All five AEAD modes exposed by CryptX: Crypt::AuthEnc::GCM, Crypt::AuthEnc::CCM, Crypt::AuthEnc::ChaCha20Poly1305, Crypt::AuthEnc::EAX, Crypt::AuthEnc::OCB
- Perl applications using the streaming decrypt_done($tag) verification form
Discovery Timeline
- 2026-06-29 - CVE-2026-13758 published to NVD
- 2026-06-30 - Last updated in NVD database
Technical Details for CVE-2026-13758
Vulnerability Analysis
The vulnerability is a classic timing side-channel [CWE-208] in cryptographic tag verification. When a caller invokes decrypt_done($tag) on any AEAD stream object, CryptX computes the expected tag internally and then compares it to the caller-supplied tag using memNE, which resolves to memcmp(a, b, len) != 0. Standard memcmp implementations return as soon as they encounter a mismatched byte, so the wall-clock duration of a rejected verification scales with the length of the correct prefix.
This behavior converts tag verification into an oracle. If an attacker can submit repeated decryption attempts with chosen tags against the same nonce, ciphertext, and associated data, and measure timings with sufficient precision, they can iterate byte positions and identify the value that produces a measurably longer comparison. Recovering the full tag yields a forgery that passes AEAD authentication, which defeats the integrity and authenticity guarantees of GCM, CCM, ChaCha20Poly1305, EAX, and OCB.
Root Cause
The root cause is the use of a data-dependent comparison routine (memcmp via memNE) inside decrypt_done rather than a constant-time comparison. The one-shot *_decrypt_verify helpers avoid the issue because tag verification is delegated to libtomcrypt, which uses a constant-time comparison internally.
Attack Vector
Exploitation requires the attacker to submit many candidate tags to a verification endpoint that exposes the streaming decrypt_done($tag) path and to observe timing differences. High attack complexity reflects the need for a stable timing channel and enough samples to defeat network jitter. No authentication or user interaction is required when the affected verification path is network-reachable.
# Patch excerpt from CryptX.xs (adds finalized state to AEAD objects)
-typedef ccm_state *Crypt__AuthEnc__CCM;
-typedef eax_state *Crypt__AuthEnc__EAX;
-typedef gcm_state *Crypt__AuthEnc__GCM;
-typedef chacha20poly1305_state *Crypt__AuthEnc__ChaCha20Poly1305;
-typedef ocb3_state *Crypt__AuthEnc__OCB;
+typedef struct cryptx_authenc_ccm_struct {
+ ccm_state state;
+ int finalized;
+} *Crypt__AuthEnc__CCM;
+typedef struct cryptx_authenc_eax_struct {
+ eax_state state;
+ int finalized;
+} *Crypt__AuthEnc__EAX;
+typedef struct cryptx_authenc_gcm_struct {
+ gcm_state state;
+ int finalized;
+} *Crypt__AuthEnc__GCM;
+typedef struct cryptx_authenc_chacha20poly1305_struct {
+ chacha20poly1305_state state;
+ int finalized;
+} *Crypt__AuthEnc__ChaCha20Poly1305;
+typedef struct cryptx_authenc_ocb_struct {
+ ocb3_state state;
+ int finalized;
+} *Crypt__AuthEnc__OCB;
Source: GitHub Commit Patch
Detection Methods for CVE-2026-13758
Indicators of Compromise
- Repeated decryption failures against the same nonce, ciphertext, and associated data from a single client or a small set of clients.
- Unusual volumes of AEAD verification requests directed at Perl services that expose decrypt_done($tag).
- Anomalous request patterns that iterate tag byte values sequentially across otherwise identical payloads.
Detection Strategies
- Inventory Perl applications that depend on CryptX and identify use of Crypt::AuthEnc::* streaming APIs by grepping for decrypt_done( in source repositories.
- Alert on applications running CryptX versions below 0.088_001 via software composition analysis (SCA) tooling.
- Instrument AEAD verification endpoints to log tag-mismatch counts per source identity, and threshold on abnormally high volumes.
Monitoring Recommendations
- Forward application authentication and decryption failure logs to a centralized analytics platform for volumetric and temporal analysis.
- Track per-client decryption failure rates and generate alerts when a single client exceeds a normal baseline within a short interval.
- Correlate repeated tag-verification failures with subsequent successful verifications from the same source, which may indicate a completed forgery attempt.
How to Mitigate CVE-2026-13758
Immediate Actions Required
- Upgrade CryptX to version 0.088_001 or later on all Perl runtimes.
- Where an immediate upgrade is not possible, migrate calling code from streaming decrypt_done($tag) to the one-shot *_decrypt_verify helpers, which use libtomcrypt's constant-time comparison.
- Rate-limit and monitor endpoints that perform AEAD tag verification to reduce the number of timing samples an attacker can collect.
Patch Information
The fix is included in CryptX 0.088_001. Details are available in the MetaCPAN Release Changes and the GitHub Commit Patch. The upstream advisory is posted on the Openwall OSS Security List Post.
Workarounds
- Replace decrypt_done($tag) calls with the corresponding *_decrypt_verify one-shot API, which performs tag comparison in constant time.
- Add server-side rate limiting and lockout on repeated AEAD verification failures for the same nonce, ciphertext, and associated data tuple.
- Enforce nonce uniqueness policies that prevent an attacker from repeatedly submitting candidate tags against the same input.
# Upgrade CryptX from CPAN to a fixed developer release or later
cpanm MIK/CryptX-0.088_001.tar.gz
# Verify installed version
perl -MCryptX -e 'print $CryptX::VERSION, "\n"'
# Locate streaming decrypt_done usage in a codebase for remediation review
grep -RIn --include='*.pm' --include='*.pl' 'decrypt_done' .
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

