Skip to content

Fix RSA-OAEP to allow zero-length plaintext per RFC 8017#10012

Open
MarkAtwood wants to merge 1 commit intowolfSSL:masterfrom
MarkAtwood:fix/rsa-oaep-allow-empty-plaintext
Open

Fix RSA-OAEP to allow zero-length plaintext per RFC 8017#10012
MarkAtwood wants to merge 1 commit intowolfSSL:masterfrom
MarkAtwood:fix/rsa-oaep-allow-empty-plaintext

Conversation

@MarkAtwood
Copy link

Summary

  • RsaPublicEncryptEx() rejects inLen == 0 with BAD_FUNC_ARG, but RFC 8017 Section 7.1.1 (RSAES-OAEP-ENCRYPT) permits zero-length messages. The only length constraint is mLen <= k - 2*hLen - 2, which mLen = 0 always satisfies.
  • RsaPrivateDecryptEx() converts a zero-length decryption result to RSA_BUFFER_E (unless WOLFSSL_RSA_DECRYPT_TO_0_LEN is defined). RFC 8017 Section 7.1.2 (RSAES-OAEP-DECRYPT) produces the original message M which may be empty.

Both OpenSSL and BoringSSL accept empty OAEP plaintexts.

Changes

Encrypt side (RsaPublicEncryptEx, line ~3321):

  • Changed inLen == 0 rejection to only apply for non-OAEP padding types
  • Added inline comment referencing RFC 8017 Section 7.1.1

Decrypt side (RsaPrivateDecryptEx, line ~3716):

  • When WOLFSSL_RSA_DECRYPT_TO_0_LEN is not defined, the ret == 0 rejection now uses constant-time masking (ctMaskEq) to allow zero-length results for WC_RSA_OAEP_PAD while preserving the existing behavior for other padding types
  • Added inline comment referencing RFC 8017 Section 7.1.2

Spec references

Testing

Verified with wolfcrypt-ring RSA-OAEP round-trip tests using SHA-1, SHA-256, SHA-384, and SHA-512 with zero-length plaintext.

🤖 Generated with Claude Code

RsaPublicEncryptEx() rejected inLen==0 unconditionally with
BAD_FUNC_ARG. RFC 8017 Section 7.1.1 (RSAES-OAEP-ENCRYPT) permits
zero-length messages: the only length constraint is
mLen <= k - 2*hLen - 2, which mLen=0 always satisfies.

RsaPrivateDecryptEx() converted a zero-length decryption result to
RSA_BUFFER_E (unless WOLFSSL_RSA_DECRYPT_TO_0_LEN was defined).
RFC 8017 Section 7.1.2 (RSAES-OAEP-DECRYPT) produces the original
message M which may be empty. The fix uses constant-time masking to
allow ret==0 when pad_type is WC_RSA_OAEP_PAD, preserving the
existing timing-safe behavior for other padding types.

Both OpenSSL and BoringSSL accept empty OAEP plaintexts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 19, 2026 02:11
Copy link
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

This PR updates RSA-OAEP handling to permit zero-length plaintexts on both encryption and decryption, aligning behavior with RFC 8017 and other TLS/crypto libraries.

Changes:

  • Relaxed RsaPublicEncryptEx() argument validation to allow inLen == 0 for OAEP padding.
  • Adjusted RsaPrivateDecryptEx() constant-time error handling to permit ret == 0 results for OAEP padding.
  • Added RFC 8017 references in inline comments to document the behavioral change.

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

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +3328 to +3329
* a zero-length input is invalid. */
if (in == NULL || (inLen == 0 && pad_type != WC_RSA_OAEP_PAD)) {
Comment on lines +3326 to +3328
* permitted: the spec requires mLen <= k - 2*hLen - 2, and mLen = 0
* satisfies this for all supported key sizes. For other padding types,
* a zero-length input is invalid. */
Comment on lines +3720 to +3721
int zeroOk = ctMaskEq(pad_type, WC_RSA_OAEP_PAD);
ret = ctMaskSelInt(ctMaskNotEq(ret, 0) | zeroOk, ret,
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.

2 participants