57afde2
diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c
57afde2
index d2ed3fd378..6a819590e6 100644
57afde2
--- a/crypto/evp/evp_enc.c
57afde2
+++ b/crypto/evp/evp_enc.c
57afde2
@@ -223,6 +223,42 @@ static int evp_cipher_init_internal(EVP_CIPHER_CTX *ctx,
57afde2
             return 0;
57afde2
     }
57afde2
 
57afde2
+#ifndef FIPS_MODULE
57afde2
+    /*
57afde2
+     * Fix for CVE-2023-5363
57afde2
+     * Passing in a size as part of the init call takes effect late
57afde2
+     * so, force such to occur before the initialisation.
57afde2
+     *
57afde2
+     * The FIPS provider's internal library context is used in a manner
57afde2
+     * such that this is not an issue.
57afde2
+     */
57afde2
+    if (params != NULL) {
57afde2
+        OSSL_PARAM param_lens[3] = { OSSL_PARAM_END, OSSL_PARAM_END,
57afde2
+                                     OSSL_PARAM_END };
57afde2
+        OSSL_PARAM *q = param_lens;
57afde2
+        const OSSL_PARAM *p;
57afde2
+
57afde2
+        p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN); 
57afde2
+        if (p != NULL)
57afde2
+            memcpy(q++, p, sizeof(*q));
57afde2
+
57afde2
+        /*
57afde2
+         * Note that OSSL_CIPHER_PARAM_AEAD_IVLEN is a synomym for
57afde2
+         * OSSL_CIPHER_PARAM_IVLEN so both are covered here.
57afde2
+         */
57afde2
+        p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_IVLEN);
57afde2
+        if (p != NULL)
57afde2
+            memcpy(q++, p, sizeof(*q));
57afde2
+
57afde2
+        if (q != param_lens) {
57afde2
+            if (!EVP_CIPHER_CTX_set_params(ctx, param_lens)) {
57afde2
+                ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_LENGTH);
57afde2
+                return 0;
57afde2
+            }
57afde2
+        }
57afde2
+    }
57afde2
+#endif
57afde2
+
57afde2
     if (enc) {
57afde2
         if (ctx->cipher->einit == NULL) {
57afde2
             ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
57afde2
diff --git a/test/evp_extra_test.c b/test/evp_extra_test.c
57afde2
index cfffa21350..2318bf6a68 100644
57afde2
--- a/test/evp_extra_test.c
57afde2
+++ b/test/evp_extra_test.c
57afde2
@@ -4851,6 +4851,253 @@ static int test_ecx_not_private_key(int tst)
57afde2
 }
3409662
 #endif /* OPENSSL_NO_EC */
57afde2
 
57afde2
+static int aes_gcm_encrypt(const unsigned char *gcm_key, size_t gcm_key_s,
57afde2
+                           const unsigned char *gcm_iv, size_t gcm_ivlen,
57afde2
+                           const unsigned char *gcm_pt, size_t gcm_pt_s,
57afde2
+                           const unsigned char *gcm_aad, size_t gcm_aad_s,
57afde2
+                           const unsigned char *gcm_ct, size_t gcm_ct_s,
57afde2
+                           const unsigned char *gcm_tag, size_t gcm_tag_s)
57afde2
+{
57afde2
+    int ret = 0;
57afde2
+    EVP_CIPHER_CTX *ctx;
57afde2
+    EVP_CIPHER *cipher = NULL;
57afde2
+    int outlen, tmplen;
57afde2
+    unsigned char outbuf[1024];
57afde2
+    unsigned char outtag[16];
57afde2
+    OSSL_PARAM params[2] = {
57afde2
+        OSSL_PARAM_END, OSSL_PARAM_END
57afde2
+    };
57afde2
+
57afde2
+    if (!TEST_ptr(ctx = EVP_CIPHER_CTX_new())
57afde2
+            || !TEST_ptr(cipher = EVP_CIPHER_fetch(testctx, "AES-256-GCM", "")))
57afde2
+        goto err;
57afde2
+
57afde2
+    params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_AEAD_IVLEN,
57afde2
+                                            &gcm_ivlen);
57afde2
+
57afde2
+    if (!TEST_true(EVP_EncryptInit_ex2(ctx, cipher, gcm_key, gcm_iv, params))
57afde2
+            || (gcm_aad != NULL
57afde2
+                && !TEST_true(EVP_EncryptUpdate(ctx, NULL, &outlen,
57afde2
+                                                gcm_aad, gcm_aad_s)))
57afde2
+            || !TEST_true(EVP_EncryptUpdate(ctx, outbuf, &outlen,
57afde2
+                                            gcm_pt, gcm_pt_s))
57afde2
+            || !TEST_true(EVP_EncryptFinal_ex(ctx, outbuf, &tmplen)))
57afde2
+        goto err;
57afde2
+
57afde2
+    params[0] = OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG,
57afde2
+                                                  outtag, sizeof(outtag));
57afde2
+
57afde2
+    if (!TEST_true(EVP_CIPHER_CTX_get_params(ctx, params))
57afde2
+            || !TEST_mem_eq(outbuf, outlen, gcm_ct, gcm_ct_s)
57afde2
+            || !TEST_mem_eq(outtag, gcm_tag_s, gcm_tag, gcm_tag_s))
57afde2
+        goto err;
57afde2
+
57afde2
+    ret = 1;
57afde2
+err:
57afde2
+    EVP_CIPHER_free(cipher);
57afde2
+    EVP_CIPHER_CTX_free(ctx);
57afde2
+
57afde2
+    return ret;
57afde2
+}
57afde2
+
57afde2
+static int aes_gcm_decrypt(const unsigned char *gcm_key, size_t gcm_key_s,
57afde2
+                           const unsigned char *gcm_iv, size_t gcm_ivlen,
57afde2
+                           const unsigned char *gcm_pt, size_t gcm_pt_s,
57afde2
+                           const unsigned char *gcm_aad, size_t gcm_aad_s,
57afde2
+                           const unsigned char *gcm_ct, size_t gcm_ct_s,
57afde2
+                           const unsigned char *gcm_tag, size_t gcm_tag_s)
57afde2
+{
57afde2
+    int ret = 0;
57afde2
+    EVP_CIPHER_CTX *ctx;
57afde2
+    EVP_CIPHER *cipher = NULL;
57afde2
+    int outlen;
57afde2
+    unsigned char outbuf[1024];
57afde2
+    OSSL_PARAM params[2] = {
57afde2
+        OSSL_PARAM_END, OSSL_PARAM_END
57afde2
+    };
57afde2
+
57afde2
+    if ((ctx = EVP_CIPHER_CTX_new()) == NULL)
57afde2
+        goto err;
57afde2
+
57afde2
+    if ((cipher = EVP_CIPHER_fetch(testctx, "AES-256-GCM", "")) == NULL)
57afde2
+        goto err;
57afde2
+
57afde2
+    params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_AEAD_IVLEN,
57afde2
+                                            &gcm_ivlen);
57afde2
+
57afde2
+    if (!TEST_true(EVP_DecryptInit_ex2(ctx, cipher, gcm_key, gcm_iv, params))
57afde2
+            || (gcm_aad != NULL
57afde2
+                && !TEST_true(EVP_DecryptUpdate(ctx, NULL, &outlen,
57afde2
+                                                gcm_aad, gcm_aad_s)))
57afde2
+            || !TEST_true(EVP_DecryptUpdate(ctx, outbuf, &outlen,
57afde2
+                                            gcm_ct, gcm_ct_s))
57afde2
+            || !TEST_mem_eq(outbuf, outlen, gcm_pt, gcm_pt_s))
57afde2
+        goto err;
57afde2
+
57afde2
+    params[0] = OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG,
57afde2
+                                                  (void*)gcm_tag, gcm_tag_s);
57afde2
+
57afde2
+    if (!TEST_true(EVP_CIPHER_CTX_set_params(ctx, params))
57afde2
+            ||!TEST_true(EVP_DecryptFinal_ex(ctx, outbuf, &outlen)))
57afde2
+        goto err;
57afde2
+
57afde2
+    ret = 1;
57afde2
+err:
57afde2
+    EVP_CIPHER_free(cipher);
57afde2
+    EVP_CIPHER_CTX_free(ctx);
57afde2
+
57afde2
+    return ret;
57afde2
+}
57afde2
+
57afde2
+static int test_aes_gcm_ivlen_change_cve_2023_5363(void)
57afde2
+{
57afde2
+    /* AES-GCM test data obtained from NIST public test vectors */
57afde2
+    static const unsigned char gcm_key[] = {
57afde2
+        0xd0, 0xc2, 0x67, 0xc1, 0x9f, 0x30, 0xd8, 0x0b, 0x89, 0x14, 0xbb, 0xbf,
57afde2
+        0xb7, 0x2f, 0x73, 0xb8, 0xd3, 0xcd, 0x5f, 0x6a, 0x78, 0x70, 0x15, 0x84,
57afde2
+        0x8a, 0x7b, 0x30, 0xe3, 0x8f, 0x16, 0xf1, 0x8b,
57afde2
+    };
57afde2
+    static const unsigned char gcm_iv[] = {
57afde2
+        0xb6, 0xdc, 0xda, 0x95, 0xac, 0x99, 0x77, 0x76, 0x25, 0xae, 0x87, 0xf8,
57afde2
+        0xa3, 0xa9, 0xdd, 0x64, 0xd7, 0x9b, 0xbd, 0x5f, 0x4a, 0x0e, 0x54, 0xca,
57afde2
+        0x1a, 0x9f, 0xa2, 0xe3, 0xf4, 0x5f, 0x5f, 0xc2, 0xce, 0xa7, 0xb6, 0x14,
57afde2
+        0x12, 0x6f, 0xf0, 0xaf, 0xfd, 0x3e, 0x17, 0x35, 0x6e, 0xa0, 0x16, 0x09,
57afde2
+        0xdd, 0xa1, 0x3f, 0xd8, 0xdd, 0xf3, 0xdf, 0x4f, 0xcb, 0x18, 0x49, 0xb8,
57afde2
+        0xb3, 0x69, 0x2c, 0x5d, 0x4f, 0xad, 0x30, 0x91, 0x08, 0xbc, 0xbe, 0x24,
57afde2
+        0x01, 0x0f, 0xbe, 0x9c, 0xfb, 0x4f, 0x5d, 0x19, 0x7f, 0x4c, 0x53, 0xb0,
57afde2
+        0x95, 0x90, 0xac, 0x7b, 0x1f, 0x7b, 0xa0, 0x99, 0xe1, 0xf3, 0x48, 0x54,
57afde2
+        0xd0, 0xfc, 0xa9, 0xcc, 0x91, 0xf8, 0x1f, 0x9b, 0x6c, 0x9a, 0xe0, 0xdc,
57afde2
+        0x63, 0xea, 0x7d, 0x2a, 0x4a, 0x7d, 0xa5, 0xed, 0x68, 0x57, 0x27, 0x6b,
57afde2
+        0x68, 0xe0, 0xf2, 0xb8, 0x51, 0x50, 0x8d, 0x3d,
57afde2
+    };
57afde2
+    static const unsigned char gcm_pt[] = {
57afde2
+        0xb8, 0xb6, 0x88, 0x36, 0x44, 0xe2, 0x34, 0xdf, 0x24, 0x32, 0x91, 0x07,
57afde2
+        0x4f, 0xe3, 0x6f, 0x81,
57afde2
+    };
57afde2
+    static const unsigned char gcm_ct[] = {
57afde2
+        0xff, 0x4f, 0xb3, 0xf3, 0xf9, 0xa2, 0x51, 0xd4, 0x82, 0xc2, 0xbe, 0xf3,
57afde2
+        0xe2, 0xd0, 0xec, 0xed,
57afde2
+    };
57afde2
+    static const unsigned char gcm_tag[] = {
57afde2
+        0xbd, 0x06, 0x38, 0x09, 0xf7, 0xe1, 0xc4, 0x72, 0x0e, 0xf2, 0xea, 0x63,
57afde2
+        0xdb, 0x99, 0x6c, 0x21,
57afde2
+    };
57afde2
+
57afde2
+    return aes_gcm_encrypt(gcm_key, sizeof(gcm_key), gcm_iv, sizeof(gcm_iv),
57afde2
+                           gcm_pt, sizeof(gcm_pt), NULL, 0,
57afde2
+                           gcm_ct, sizeof(gcm_ct), gcm_tag, sizeof(gcm_tag))
57afde2
+        && aes_gcm_decrypt(gcm_key, sizeof(gcm_key), gcm_iv, sizeof(gcm_iv),
57afde2
+                           gcm_pt, sizeof(gcm_pt), NULL, 0,
57afde2
+                           gcm_ct, sizeof(gcm_ct), gcm_tag, sizeof(gcm_tag));
57afde2
+}
57afde2
+
57afde2
+#ifndef OPENSSL_NO_RC4
57afde2
+static int rc4_encrypt(const unsigned char *rc4_key, size_t rc4_key_s,
57afde2
+                       const unsigned char *rc4_pt, size_t rc4_pt_s,
57afde2
+                       const unsigned char *rc4_ct, size_t rc4_ct_s)
57afde2
+{
57afde2
+    int ret = 0;
57afde2
+    EVP_CIPHER_CTX *ctx;
57afde2
+    EVP_CIPHER *cipher = NULL;
57afde2
+    int outlen, tmplen;
57afde2
+    unsigned char outbuf[1024];
57afde2
+    OSSL_PARAM params[2] = {
57afde2
+        OSSL_PARAM_END, OSSL_PARAM_END
57afde2
+    };
57afde2
+
57afde2
+    if (!TEST_ptr(ctx = EVP_CIPHER_CTX_new())
57afde2
+            || !TEST_ptr(cipher = EVP_CIPHER_fetch(testctx, "RC4", "")))
57afde2
+        goto err;
57afde2
+
57afde2
+    params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_KEYLEN,
57afde2
+                                            &rc4_key_s);
57afde2
+
57afde2
+    if (!TEST_true(EVP_EncryptInit_ex2(ctx, cipher, rc4_key, NULL, params))
57afde2
+            || !TEST_true(EVP_EncryptUpdate(ctx, outbuf, &outlen,
57afde2
+                                            rc4_pt, rc4_pt_s))
57afde2
+            || !TEST_true(EVP_EncryptFinal_ex(ctx, outbuf, &tmplen)))
57afde2
+        goto err;
57afde2
+
57afde2
+    if (!TEST_mem_eq(outbuf, outlen, rc4_ct, rc4_ct_s))
57afde2
+        goto err;
57afde2
+
57afde2
+    ret = 1;
57afde2
+err:
57afde2
+    EVP_CIPHER_free(cipher);
57afde2
+    EVP_CIPHER_CTX_free(ctx);
57afde2
+
57afde2
+    return ret;
57afde2
+}
57afde2
+
57afde2
+static int rc4_decrypt(const unsigned char *rc4_key, size_t rc4_key_s,
57afde2
+                       const unsigned char *rc4_pt, size_t rc4_pt_s,
57afde2
+                       const unsigned char *rc4_ct, size_t rc4_ct_s)
57afde2
+{
57afde2
+    int ret = 0;
57afde2
+    EVP_CIPHER_CTX *ctx;
57afde2
+    EVP_CIPHER *cipher = NULL;
57afde2
+    int outlen;
57afde2
+    unsigned char outbuf[1024];
57afde2
+    OSSL_PARAM params[2] = {
57afde2
+        OSSL_PARAM_END, OSSL_PARAM_END
57afde2
+    };
57afde2
+
57afde2
+    if ((ctx = EVP_CIPHER_CTX_new()) == NULL)
57afde2
+        goto err;
57afde2
+
57afde2
+    if ((cipher = EVP_CIPHER_fetch(testctx, "RC4", "")) == NULL)
57afde2
+        goto err;
57afde2
+
57afde2
+    params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_KEYLEN,
57afde2
+                                            &rc4_key_s);
57afde2
+
57afde2
+    if (!TEST_true(EVP_DecryptInit_ex2(ctx, cipher, rc4_key, NULL, params))
57afde2
+            || !TEST_true(EVP_DecryptUpdate(ctx, outbuf, &outlen,
57afde2
+                                            rc4_ct, rc4_ct_s))
57afde2
+            || !TEST_mem_eq(outbuf, outlen, rc4_pt, rc4_pt_s))
57afde2
+        goto err;
57afde2
+
57afde2
+    ret = 1;
57afde2
+err:
57afde2
+    EVP_CIPHER_free(cipher);
57afde2
+    EVP_CIPHER_CTX_free(ctx);
57afde2
+
57afde2
+    return ret;
57afde2
+}
57afde2
+
57afde2
+static int test_aes_rc4_keylen_change_cve_2023_5363(void)
57afde2
+{
57afde2
+    /* RC4 test data obtained from RFC 6229 */
57afde2
+    static const struct {
57afde2
+        unsigned char key[5];
57afde2
+        unsigned char padding[11];
57afde2
+    } rc4_key = {
57afde2
+        {   /* Five bytes of key material */
57afde2
+            0x83, 0x32, 0x22, 0x77, 0x2a,
57afde2
+        },
57afde2
+        {   /* Random padding to 16 bytes */
57afde2
+            0x80, 0xad, 0x97, 0xbd, 0xc9, 0x73, 0xdf, 0x8a, 0xaa, 0x32, 0x91
57afde2
+        }
57afde2
+    };
57afde2
+    static const unsigned char rc4_pt[] = {
57afde2
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
57afde2
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
57afde2
+    };
57afde2
+    static const unsigned char rc4_ct[] = {
57afde2
+        0x80, 0xad, 0x97, 0xbd, 0xc9, 0x73, 0xdf, 0x8a,
57afde2
+        0x2e, 0x87, 0x9e, 0x92, 0xa4, 0x97, 0xef, 0xda
57afde2
+    };
57afde2
+
57afde2
+    if (lgcyprov == NULL)
57afde2
+        return TEST_skip("Test requires legacy provider to be loaded");
57afde2
+
57afde2
+    return rc4_encrypt(rc4_key.key, sizeof(rc4_key.key),
57afde2
+                       rc4_pt, sizeof(rc4_pt), rc4_ct, sizeof(rc4_ct))
57afde2
+        && rc4_decrypt(rc4_key.key, sizeof(rc4_key.key),
57afde2
+                       rc4_pt, sizeof(rc4_pt), rc4_ct, sizeof(rc4_ct));
57afde2
+}
57afde2
+#endif
57afde2
+
57afde2
 int setup_tests(void)
57afde2
 {
57afde2
     OPTION_CHOICE o;
57afde2
@@ -4994,6 +5241,12 @@ int setup_tests(void)
57afde2
 
57afde2
     ADD_ALL_TESTS(test_ecx_short_keys, OSSL_NELEM(ecxnids));
57afde2
 
57afde2
+    /* Test cases for CVE-2023-5363 */
57afde2
+    ADD_TEST(test_aes_gcm_ivlen_change_cve_2023_5363);
57afde2
+#ifndef OPENSSL_NO_RC4
57afde2
+    ADD_TEST(test_aes_rc4_keylen_change_cve_2023_5363);
57afde2
+#endif
57afde2
+
3409662
 #ifndef OPENSSL_NO_EC
3409662
     ADD_ALL_TESTS(test_ecx_not_private_key, OSSL_NELEM(keys));
3409662
 #endif