diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index 3a32f915b7..389ff03d13 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -3318,7 +3318,15 @@ static int RsaPublicEncryptEx(const byte* in, word32 inLen, byte* out, RsaPadding padding; #endif - if (in == NULL || inLen == 0 || out == NULL || key == NULL) { + if (out == NULL || key == NULL) { + return BAD_FUNC_ARG; + } + + /* For OAEP padding (RFC 8017, Section 7.1.1), zero-length messages are + * 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. */ + if (in == NULL || (inLen == 0 && pad_type != WC_RSA_OAEP_PAD)) { return BAD_FUNC_ARG; } @@ -3706,8 +3714,13 @@ static int RsaPrivateDecryptEx(const byte* in, word32 inLen, byte* out, ret = ctMaskSelInt(ctMaskLTE(ret, (int)outLen), ret, WC_NO_ERR_TRACE(RSA_BUFFER_E)); #ifndef WOLFSSL_RSA_DECRYPT_TO_0_LEN - ret = ctMaskSelInt(ctMaskNotEq(ret, 0), ret, - WC_NO_ERR_TRACE(RSA_BUFFER_E)); + /* RFC 8017 Section 7.1.2: OAEP decryption may produce a valid + * zero-length message. Only reject ret==0 for non-OAEP types. */ + { + int zeroOk = ctMaskEq(pad_type, WC_RSA_OAEP_PAD); + ret = ctMaskSelInt(ctMaskNotEq(ret, 0) | zeroOk, ret, + WC_NO_ERR_TRACE(RSA_BUFFER_E)); + } #endif #else if (outLen < (word32)ret)