Skip to content

[3.5,3.4] Reject explicitly supplied invalid tags and generate tags for empty AEAD messages - #32416

Closed
mbroz wants to merge 2 commits into
openssl:openssl-3.5from
mbroz:aead-null-3-5
Closed

mbroz wants to merge 2 commits into
openssl:openssl-3.5from
mbroz:aead-null-3-5

Conversation

@mbroz

@mbroz mbroz commented Aug 18, 2026

Copy link
Copy Markdown
Member

Fixes #32258

(clone for 3.4 and 3.5)

This backports #32173 (commit 5741d29) to openssl-3.6, openssl-3.5, and openssl-3.4, with stable-branch adaptations and dedicated regression coverage.

Backport status:

  • the PR head is based directly on the current openssl-3.6 tip and is intended to target openssl-3.6
  • the same two commits cherry-pick cleanly onto the current openssl-3.5 and openssl-3.4 tips, so this PR is intended for the branch: 3.6, branch: 3.5, and branch: 3.4 labels
  • openssl-4.0 requires a separate branch-specific backport because its ChaCha20-Poly1305 callback layout differs

For the affected built-in provider implementations, a call to EVP_Cipher(ctx, out, NULL, 0) is dispatched to the ccipher callback as a NULL-input terminal call. These callbacks don't consistently perform the empty-message tag operation:

  • ChaCha20-Poly1305 and AES-OCB decryption can return success without verifying an explicitly supplied authentication tag. This occurs with or without AAD, so a corrupted tag produces the same zero-byte success result as a valid tag.
  • AES-GCM-SIV encryption fails to generate a tag when Final is the first empty-message operation. Its corresponding decryption path also doesn't propagate failures from empty-message tag recomputation.

An empty plaintext does not make authentication irrelevant: a valid tag computed under the expected key and nonce authenticates the empty ciphertext and any AAD. Accepting an invalid tag can therefore bypass transcript authentication, key confirmation, or authenticated state-transition checks in applications using tag-only AEAD messages.

The backport:

  • routes NULL AES-OCB input through aes_ocb_block_final, which generates or verifies the tag
  • introduces a dedicated ChaCha20-Poly1305 Update callback for the stable implementation, preserving zero-length Update as a no-op while allowing the NULL-input ccipher call to perform the terminal tag operation
  • generates the AES-GCM-SIV tag when Final is the first empty-message operation and propagates empty-message tag recomputation failures during decryption
  • adds regression tests covering correct-tag acceptance, corrupted-tag rejection, and encryption tag generation, with and without AAD.

The 3.6 version changes cipher_chacha20_poly1305.c.in. When the same commits are cherry-picked onto 3.5 and 3.4, Git correctly maps that change to those branches' cipher_chacha20_poly1305.c source file.

Validation:

  • openssl-3.6: configured with --strict-warnings no-shared enable-fips, built with GCC 13.3 under WSL2, and passed make test TESTS='test_evp test_evp_extra' (176 tests).
  • openssl-3.5: configured with CPPFLAGS=-ansi, --strict-warnings, no-asm, no-shared, enable-fips, and -D_DEFAULT_SOURCE; built with GCC 13.3 under WSL2 and passed make test TESTS='test_evp test_evp_extra' (175 tests).
  • openssl-3.4: configured with the same options as 3.5, built with GCC 13.3 under WSL2, and passed make test TESTS='test_evp test_evp_extra' (126 tests).

The 4.0 implementation has a different ChaCha20-Poly1305 callback layout and is prepared as dedicated PR #32300.

Checklist
  • tests are added or updated

bbbrumley and others added 2 commits August 18, 2026 15:05
For the affected OpenSSL built-in provider AEAD implementations,
EVP_Cipher(ctx, out, NULL, 0) reaches the ccipher callback as a
NULL-input terminal call. OCB and ChaCha20-Poly1305 took an early exit
on an empty message, with or without AAD, and returned success without
comparing an explicitly supplied tag. Consequently a corrupted tag was
accepted before this change.

Make these built-in callbacks perform their terminal tag operation,
aligning their explicit-tag handling with the streaming Final path
without defining NULL input as part of the generic EVP_Cipher()
contract.

AES-GCM-SIV also failed to generate a tag when Final was its first
empty-message operation. Generate the tag in that case and propagate
failures from the matching empty-message decrypt operation.

The stable ChaCha20-Poly1305 implementation aliases Update to the
one-shot cipher callback, so this backport introduces a dedicated Update
callback to preserve zero-length Update as a no-op.

Follow-up to openssl#31555
Fixes openssl#32258

Assisted-by: Claude:claude-opus-4-8
Assisted-by: Codex:gpt-5.6-sol

(cherry picked from commit 5741d29)

Co-authored-by: Mounir IDRASSI <[email protected]>
Generate an empty-message tag with the streaming path, then check that
EVP_Cipher() decryption accepts the correct tag and rejects a corrupted
one. Also verify that EVP_Cipher() encryption produces the same tag.

Cover AES-OCB, ChaCha20-Poly1305, and AES-GCM-SIV, with and without AAD.

Assisted-by: Codex:gpt-5.6-sol
@mbroz
mbroz requested a review from idrassi August 18, 2026 13:17
@mbroz mbroz self-assigned this Aug 18, 2026
@mbroz mbroz added triaged: bug The issue/pr is/fixes a bug branch: 3.4 Applies to openssl-3.4 branch: 3.5 Applies to openssl-3.5 labels Aug 18, 2026
@openssl-ci-bot openssl-ci-bot Bot added the approval: review pending This pull request needs review by a committer label Aug 18, 2026
@t8m t8m added the tests: present The PR has suitable tests present label Aug 18, 2026
@github-actions github-actions Bot added the severity: fips change The pull request changes FIPS provider sources label Aug 18, 2026
@mbroz
mbroz requested a review from nhorman August 18, 2026 13:26
@openssl-ci-bot openssl-ci-bot Bot added approval: done This pull request has the required number of approvals and removed approval: review pending This pull request needs review by a committer labels Aug 18, 2026
@t8m t8m added approval: ready to merge The 24 hour grace period has passed, ready to merge and removed approval: done This pull request has the required number of approvals labels Aug 19, 2026
@t8m

t8m commented Aug 19, 2026

Copy link
Copy Markdown
Member

Merged to the 3.5 and 3.4 branches. Thank you.

@t8m t8m closed this Aug 19, 2026
openssl-machine pushed a commit that referenced this pull request Aug 19, 2026
For the affected OpenSSL built-in provider AEAD implementations,
EVP_Cipher(ctx, out, NULL, 0) reaches the ccipher callback as a
NULL-input terminal call. OCB and ChaCha20-Poly1305 took an early exit
on an empty message, with or without AAD, and returned success without
comparing an explicitly supplied tag. Consequently a corrupted tag was
accepted before this change.

Make these built-in callbacks perform their terminal tag operation,
aligning their explicit-tag handling with the streaming Final path
without defining NULL input as part of the generic EVP_Cipher()
contract.

AES-GCM-SIV also failed to generate a tag when Final was its first
empty-message operation. Generate the tag in that case and propagate
failures from the matching empty-message decrypt operation.

The stable ChaCha20-Poly1305 implementation aliases Update to the
one-shot cipher callback, so this backport introduces a dedicated Update
callback to preserve zero-length Update as a no-op.

Follow-up to #31555
Fixes #32258
Fixes CVE-2026-75803

Assisted-by: Claude:claude-opus-4-8
Assisted-by: Codex:gpt-5.6-sol

(cherry picked from commit 5741d29)

Co-authored-by: Mounir IDRASSI <[email protected]>
Reviewed-by: Bob Beck <[email protected]>
Reviewed-by: Tomas Mraz <[email protected]>
Merge-date: Wed Aug 19 17:41:16 2026
Merged-from: #32416
openssl-machine pushed a commit that referenced this pull request Aug 19, 2026
Generate an empty-message tag with the streaming path, then check that
EVP_Cipher() decryption accepts the correct tag and rejects a corrupted
one. Also verify that EVP_Cipher() encryption produces the same tag.

Cover AES-OCB, ChaCha20-Poly1305, and AES-GCM-SIV, with and without AAD.

Assisted-by: Codex:gpt-5.6-sol
Reviewed-by: Bob Beck <[email protected]>
Reviewed-by: Tomas Mraz <[email protected]>
Merge-date: Wed Aug 19 17:41:17 2026
Merged-from: #32416
openssl-machine pushed a commit that referenced this pull request Aug 19, 2026
For the affected OpenSSL built-in provider AEAD implementations,
EVP_Cipher(ctx, out, NULL, 0) reaches the ccipher callback as a
NULL-input terminal call. OCB and ChaCha20-Poly1305 took an early exit
on an empty message, with or without AAD, and returned success without
comparing an explicitly supplied tag. Consequently a corrupted tag was
accepted before this change.

Make these built-in callbacks perform their terminal tag operation,
aligning their explicit-tag handling with the streaming Final path
without defining NULL input as part of the generic EVP_Cipher()
contract.

AES-GCM-SIV also failed to generate a tag when Final was its first
empty-message operation. Generate the tag in that case and propagate
failures from the matching empty-message decrypt operation.

The stable ChaCha20-Poly1305 implementation aliases Update to the
one-shot cipher callback, so this backport introduces a dedicated Update
callback to preserve zero-length Update as a no-op.

Follow-up to #31555
Fixes #32258
Fixes CVE-2026-75803

Assisted-by: Claude:claude-opus-4-8
Assisted-by: Codex:gpt-5.6-sol

(cherry picked from commit 5741d29)

Co-authored-by: Mounir IDRASSI <[email protected]>
Reviewed-by: Bob Beck <[email protected]>
Reviewed-by: Tomas Mraz <[email protected]>
Merge-date: Wed Aug 19 17:41:16 2026
Merged-from: #32416
openssl-machine pushed a commit that referenced this pull request Aug 19, 2026
Generate an empty-message tag with the streaming path, then check that
EVP_Cipher() decryption accepts the correct tag and rejects a corrupted
one. Also verify that EVP_Cipher() encryption produces the same tag.

Cover AES-OCB, ChaCha20-Poly1305, and AES-GCM-SIV, with and without AAD.

Assisted-by: Codex:gpt-5.6-sol
Reviewed-by: Bob Beck <[email protected]>
Reviewed-by: Tomas Mraz <[email protected]>
Merge-date: Wed Aug 19 17:41:17 2026
Merged-from: #32416
(cherry picked from commit e9fb43a)
openssl-machine pushed a commit that referenced this pull request Aug 25, 2026
3.5.8 CHANGES.md includes the following:
 * CVE-2026-14456, CVE-2026-14457, CVE-2026-18798, CVE-2026-54874,
   CVE-2026-63072, CVE-2026-63073, CVE-2026-63074, CVE-2026-63075,
   CVE-2026-63076, CVE-2026-75803
 * #31174
   "Enforce RFC 8446 ticket lifetime limit for TLS 1.3 client"
   (already present)
 * #31572
   "[4.0, 3.6, 3.5, 3.4] Add icx compiler version support in perl asm scripts"
 * #31749
   "Add documentation for OPENSSL_armcap"
 * #32052
   "QUIC server: limit the number of pending connections"
   (included as CVE-2026-14456)
 * #32416
   "[3.5,3.4] Reject explicitly supplied invalid tags and generate tags for empty AEAD messages"
   (included as CVE-2026-75803)
 * #32427
   "Backport #32256 openssl 4.0 to 3.0"

3.5.8 NEWS.md includes the following:
 * CVE-2026-14456, CVE-2026-14457, CVE-2026-18798, CVE-2026-54874,
   CVE-2026-63072, CVE-2026-63073, CVE-2026-63074, CVE-2026-63075,
   CVE-2026-63076, CVE-2026-75803
 * #32052
   "QUIC server: limit the number of pending connections"
   (included as CVE-2026-14456)
 * #32416
   "[3.5,3.4] Reject explicitly supplied invalid tags and generate tags for empty AEAD messages"
   (included as CVE-2026-75803)
 * #32427
   "Backport #32256 openssl 4.0 to 3.0"

Signed-off-by: Eugene Syromiatnikov <[email protected]>
Reviewed-by: Milan Broz <[email protected]>
Reviewed-by: Tomas Mraz <[email protected]>
Reviewed-by: Bob Beck <[email protected]>
Merge-date: Tue Aug 25 11:36:56 2026
openssl-machine pushed a commit that referenced this pull request Aug 25, 2026
3.4.7 CHANGES.md includes the following:
 * CVE-2026-14457, CVE-2026-54874, CVE-2026-63072, CVE-2026-63073,
   CVE-2026-63074, CVE-2026-63075, CVE-2026-63076, CVE-2026-75803
 * #31174
   "Enforce RFC 8446 ticket lifetime limit for TLS 1.3 client"
   (already present)
 * #31572
   "[4.0, 3.6, 3.5, 3.4] Add icx compiler version support in perl asm scripts"
 * #32416
   "[3.5,3.4] Reject explicitly supplied invalid tags and generate tags for empty AEAD messages"
   (included as CVE-2026-75803)
 * #32427
   "Backport #32256 openssl 4.0 to 3.0"

3.4.7 NEWS.md includes the following:
 * CVE-2026-14457, CVE-2026-54874, CVE-2026-63072, CVE-2026-63073,
   CVE-2026-63074, CVE-2026-63075, CVE-2026-63076, CVE-2026-75803
 * #32416
   "[3.5,3.4] Reject explicitly supplied invalid tags and generate tags for empty AEAD messages"
   (included as CVE-2026-75803)
 * #32427
   "Backport #32256 openssl 4.0 to 3.0"

Signed-off-by: Eugene Syromiatnikov <[email protected]>
Reviewed-by: Milan Broz <[email protected]>
Reviewed-by: Tomas Mraz <[email protected]>
Reviewed-by: Bob Beck <[email protected]>
Merge-date: Tue Aug 25 11:37:42 2026
raspbian-autopush pushed a commit to raspbian-packages/openssl that referenced this pull request Sep 4, 2026
For the affected OpenSSL built-in provider AEAD implementations,
EVP_Cipher(ctx, out, NULL, 0) reaches the ccipher callback as a
NULL-input terminal call. OCB and ChaCha20-Poly1305 took an early exit
on an empty message, with or without AAD, and returned success without
comparing an explicitly supplied tag. Consequently a corrupted tag was
accepted before this change.

Make these built-in callbacks perform their terminal tag operation,
aligning their explicit-tag handling with the streaming Final path
without defining NULL input as part of the generic EVP_Cipher()
contract.

AES-GCM-SIV also failed to generate a tag when Final was its first
empty-message operation. Generate the tag in that case and propagate
failures from the matching empty-message decrypt operation.

The stable ChaCha20-Poly1305 implementation aliases Update to the
one-shot cipher callback, so this backport introduces a dedicated Update
callback to preserve zero-length Update as a no-op.

Follow-up to #31555
Fixes #32258
Fixes CVE-2026-75803

Assisted-by: Claude:claude-opus-4-8
Assisted-by: Codex:gpt-5.6-sol

(cherry picked from commit 5741d29a5f356e05262cd0936a472a9961398d53)

Co-authored-by: Mounir IDRASSI <[email protected]>
Reviewed-by: Bob Beck <[email protected]>
Reviewed-by: Tomas Mraz <[email protected]>
Merge-date: Wed Aug 19 17:41:16 2026
Merged-from: openssl/openssl#32416

Gbp-Pq: Name Check-the-tag-on-EVP_Cipher-finalize-Poly1305-and-OCB-AEA.patch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approval: ready to merge The 24 hour grace period has passed, ready to merge branch: 3.4 Applies to openssl-3.4 branch: 3.5 Applies to openssl-3.5 severity: fips change The pull request changes FIPS provider sources tests: present The PR has suitable tests present triaged: bug The issue/pr is/fixes a bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Invalid tags can be accepted for empty ChaCha20-Poly1305 and OCB ciphertexts via EVP_Cipher()

5 participants