Skip to content

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

Open
MarkAtwood wants to merge 2 commits intowolfSSL:masterfrom
MarkAtwood:fix/chacha20poly1305-empty-plaintext
Open

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

Conversation

@MarkAtwood
Copy link
Copy Markdown

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

🤖 Generated with Claude Code

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 2 times, most recently from 1edcdc0 to 4c49ea4 Compare April 17, 2026 21:27
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.
@MarkAtwood MarkAtwood force-pushed the fix/chacha20poly1305-empty-plaintext branch from 4c49ea4 to 5e899a1 Compare April 17, 2026 21:32
@MarkAtwood
Copy link
Copy Markdown
Author

/cc @wolfSSL-Fenrir-bot please review

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 18, 2026

MemBrowse Memory Report

gcc-arm-cortex-m4

  • FLASH: .rodata.CSWTCH.1 +40 B, .rodata.str1.1 +491 B, .rodata.wolfSSL_ERR_reason_error_string.str1.1 +29 B, .text +960 B (+0.8%, 196,859 B / 262,144 B, total: 75% used)
  • RAM: .bss +8 B (+1.0%, 828 B / 65,536 B, total: 1% used)

gcc-arm-cortex-m4-baremetal

  • FLASH: .text +768 B (+1.2%, 64,307 B / 262,144 B, total: 25% used)
  • RAM: .bss +4 B (+0.6%, 644 B / 65,536 B, total: 1% used)

gcc-arm-cortex-m4-min-ecc

  • FLASH: .text +768 B (+1.3%, 59,893 B / 262,144 B, total: 23% used)
  • RAM: .bss +4 B (+0.6%, 668 B / 65,536 B, total: 1% used)

gcc-arm-cortex-m4-tls12

  • FLASH: .text +896 B (+0.8%, 120,314 B / 262,144 B, total: 46% used)
  • RAM: .bss +8 B (+1.0%, 808 B / 65,536 B, total: 1% used)

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
Copy link
Copy Markdown
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.

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)

5 participants