Skip to content

Fix ChaCha20-Poly1305 Final() to allow empty plaintext and AAD#10046

Open
MarkAtwood wants to merge 3 commits into
wolfSSL:masterfrom
MarkAtwood:fix/chacha20poly1305-empty-plaintext
Open

Fix ChaCha20-Poly1305 Final() to allow empty plaintext and AAD#10046
MarkAtwood wants to merge 3 commits into
wolfSSL:masterfrom
MarkAtwood:fix/chacha20poly1305-empty-plaintext

Conversation

@MarkAtwood
Copy link
Copy Markdown
Contributor

@MarkAtwood MarkAtwood commented Mar 23, 2026

Summary

  • wc_ChaCha20Poly1305_Final() rejected CHACHA20_POLY1305_STATE_READY with BAD_STATE_E, which occurs when neither UpdateAad nor UpdateData has been called (both AAD and plaintext are empty)
  • RFC 8439 Section 2.8 permits this and produces a well-defined authentication tag
  • Affects both the streaming API and the one-shot wc_ChaCha20Poly1305_Encrypt/Decrypt functions which call through it

Fixes #10040

Test plan

  • Verify existing ChaCha20-Poly1305 tests still pass
  • Confirm empty plaintext + empty AAD produces correct authentication tag
  • Verify Wycheproof test vectors tc 2 and tc 3 pass through the streaming API

Copilot AI review requested due to automatic review settings March 23, 2026 15:13
Copy link
Copy Markdown
Member

@dgarske dgarske left a comment

Choose a reason for hiding this comment

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

Many of the CI tests are failing now:

ChaCha20-Poly1305 AEAD test failed!
 error L=10590 code=0 (ok)
 [fiducial line numbers: 11340 31712 53140 66641]
Exiting main with return code: -1

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Updates the ChaCha20-Poly1305 streaming finalization logic to permit generating an authentication tag when both plaintext and AAD are empty, aligning behavior with RFC 8439 and fixing the reported BAD_STATE_E error path.

Changes:

  • Allow wc_ChaCha20Poly1305_Final() to accept the CHACHA20_POLY1305_STATE_READY state (no prior AAD/data updates).
  • Preserve existing state validation for AAD and DATA states while continuing to reject other invalid states.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown

@wolfSSL-Fenrir-bot wolfSSL-Fenrir-bot left a comment

Choose a reason for hiding this comment

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

Fenrir Automated Review — PR #10046

Scan targets checked: wolfcrypt-bugs, wolfcrypt-src

No new issues found in the changed files. ✅

@MarkAtwood MarkAtwood force-pushed the fix/chacha20poly1305-empty-plaintext branch 3 times, most recently from 4c49ea4 to 5e899a1 Compare April 17, 2026 21:32
@MarkAtwood
Copy link
Copy Markdown
Contributor Author

/cc @wolfSSL-Fenrir-bot please review

@MarkAtwood
Copy link
Copy Markdown
Contributor Author

Fixed the CI failure: the existing bad-state test at line 10987 manually set aead.state = CHACHA20_POLY1305_STATE_READY without calling Init, then expected BAD_STATE_E. Since the fix now accepts READY state, that assertion was wrong.

Replaced it with a positive test using Wycheproof tc2 (key/iv/tag from the test corpus): calls Init properly, then Final with no UpdateAad/UpdateData, and verifies the output tag matches the expected value. This directly tests the RFC 8439 §2.8 empty-plaintext case.

@MarkAtwood MarkAtwood force-pushed the fix/chacha20poly1305-empty-plaintext branch 2 times, most recently from 4445845 to eb92e4a Compare June 4, 2026 00:24
@MarkAtwood
Copy link
Copy Markdown
Contributor Author

retest this please

@ColtonWilley
Copy link
Copy Markdown
Contributor

Jenkins retest this please

wc_ChaCha20Poly1305_Final() rejected CHACHA20_POLY1305_STATE_READY,
blocking use when no data or AAD was ever provided. RFC 8439 §2.8
permits empty plaintext and produces a well-defined authentication tag.

Found via Wycheproof test vectors.
Replace the READY-state BAD_STATE_E assertion (which the fix renders
obsolete) with a positive Wycheproof tc2 test: empty plaintext + empty
AAD through the streaming API must produce the correct authentication
tag per RFC 8439 Section 2.8.
@MarkAtwood MarkAtwood force-pushed the fix/chacha20poly1305-empty-plaintext branch from eb92e4a to 933b7c2 Compare June 4, 2026 22:37
@MarkAtwood
Copy link
Copy Markdown
Contributor Author

Rebased onto current master to fix the widespread CI failures (stale base branch). Also fixed non-ASCII §Section in test comments. The ChaCha20-Poly1305 test passes — the original CI failure dgarske flagged was from the first commit before the test was updated. Ready for re-review.

Update test_wc_ChaCha20Poly1305_Stream to expect success (not
BAD_STATE_E) when calling Final() immediately after Init(), since
empty plaintext + empty AAD is valid per RFC 8439 Section 2.8.
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.

wc_ChaCha20Poly1305_Final rejects valid empty-plaintext + empty-AAD input (BAD_STATE_E)

6 participants