Skip to content

Commit 1edcdc0

Browse files
committed
Fix ChaCha20-Poly1305 and RSA-OAEP to allow empty plaintext
ChaCha20-Poly1305 Final() rejected the READY state (no data or AAD provided), though RFC 8439 §2.8 explicitly permits empty plaintext and produces a well-defined authentication tag. RSA-OAEP rejected zero-length plaintexts at both encrypt and decrypt. RFC 8017 §7.1.1 permits empty messages; OpenSSL and BoringSSL both accept them. Found via Wycheproof test vectors.
1 parent d343ea6 commit 1edcdc0

File tree

2 files changed

+18
-4
lines changed

2 files changed

+18
-4
lines changed

wolfcrypt/src/chacha20_poly1305.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,8 @@ int wc_ChaCha20Poly1305_Final(ChaChaPoly_Aead* aead,
275275
if (aead == NULL || outAuthTag == NULL) {
276276
return BAD_FUNC_ARG;
277277
}
278-
if (aead->state != CHACHA20_POLY1305_STATE_AAD &&
278+
if (aead->state != CHACHA20_POLY1305_STATE_READY &&
279+
aead->state != CHACHA20_POLY1305_STATE_AAD &&
279280
aead->state != CHACHA20_POLY1305_STATE_DATA) {
280281
return BAD_STATE_E;
281282
}

wolfcrypt/src/rsa.c

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

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

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

0 commit comments

Comments
 (0)