Skip to content

Commit a0752c3

Browse files
MarkAtwoodclaude
andcommitted
Fix RSA-OAEP to allow zero-length plaintext per RFC 8017
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>
1 parent 86db2d4 commit a0752c3

File tree

1 file changed

+16
-3
lines changed

1 file changed

+16
-3
lines changed

wolfcrypt/src/rsa.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3355,7 +3355,15 @@ static int RsaPublicEncryptEx(const byte* in, word32 inLen, byte* out,
33553355
RsaPadding padding;
33563356
#endif
33573357

3358-
if (in == NULL || inLen == 0 || out == NULL || key == NULL) {
3358+
if (out == NULL || key == NULL) {
3359+
return BAD_FUNC_ARG;
3360+
}
3361+
3362+
/* For OAEP padding (RFC 8017, Section 7.1.1), zero-length messages are
3363+
* permitted: the spec requires mLen <= k - 2*hLen - 2, and mLen = 0
3364+
* satisfies this for all supported key sizes. For other padding types,
3365+
* a zero-length input is invalid. */
3366+
if (in == NULL || (inLen == 0 && pad_type != WC_RSA_OAEP_PAD)) {
33593367
return BAD_FUNC_ARG;
33603368
}
33613369

@@ -3753,8 +3761,13 @@ static int RsaPrivateDecryptEx(const byte* in, word32 inLen, byte* out,
37533761
ret = ctMaskSelInt(ctMaskLTE(ret, (int)outLen), ret,
37543762
WC_NO_ERR_TRACE(RSA_BUFFER_E));
37553763
#ifndef WOLFSSL_RSA_DECRYPT_TO_0_LEN
3756-
ret = ctMaskSelInt(ctMaskNotEq(ret, 0), ret,
3757-
WC_NO_ERR_TRACE(RSA_BUFFER_E));
3764+
/* RFC 8017 Section 7.1.2: OAEP decryption may produce a valid
3765+
* zero-length message. Only reject ret==0 for non-OAEP types. */
3766+
{
3767+
int zeroOk = ctMaskEq(pad_type, WC_RSA_OAEP_PAD);
3768+
ret = ctMaskSelInt(ctMaskNotEq(ret, 0) | zeroOk, ret,
3769+
WC_NO_ERR_TRACE(RSA_BUFFER_E));
3770+
}
37583771
#endif
37593772
#else
37603773
if (outLen < (word32)ret)

0 commit comments

Comments
 (0)