]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Add negative length validation in EVP_EncryptUpdate and EVP_DecryptUpdate
authorPranavjeet-Naidu <pranavjeetnaidu@gmail.com>
Tue, 24 Mar 2026 23:45:30 +0000 (05:15 +0530)
committerEugene Syromiatnikov <esyr@openssl.org>
Tue, 31 Mar 2026 02:14:29 +0000 (04:14 +0200)
Added input length validation checks to prevent potential security issues
when negative values are passed to EVP_EncryptUpdate and EVP_DecryptUpdate.
These functions cast inl (int) to size_t without validation, which could lead
to unexpectedly large buffer allocation attempts or unintended behavior with
negative inputs.

Validation is performed early in both functions to ensure only valid,
non-negative lengths are processed. Error is reported via EVP_R_INVALID_LENGTH.

Fixes: https://github.com/openssl/openssl/issues/30486
Reviewed-by: Paul Dale <paul.dale@oracle.com>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Reviewed-by: Eugene Syromiatnikov <esyr@openssl.org>
MergeDate: Tue Mar 31 02:10:52 2026
(Merged from https://github.com/openssl/openssl/pull/30560)

(cherry picked from commit d29c165122bd480ca736a3eeb21d88a6b433ead3)

crypto/evp/evp_enc.c
test/evp_extra_test.c

index 0d2c26052ed37ca1c514854e4e7f60c1b01d6354..723be6e066b6f4dfc162e829a6d2feeca31e63ea 100644 (file)
@@ -654,6 +654,11 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
     size_t soutl, inl_ = (size_t)inl;
     int blocksize;
 
+    if (inl < 0) {
+        ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_LENGTH);
+        return 0;
+    }
+
     if (ossl_likely(outl != NULL)) {
         *outl = 0;
     } else {
@@ -760,6 +765,11 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
     size_t soutl, inl_ = (size_t)inl;
     int blocksize;
 
+    if (inl < 0) {
+        ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_LENGTH);
+        return 0;
+    }
+
     if (ossl_likely(outl != NULL)) {
         *outl = 0;
     } else {
index b975b68f7ecf3559637312c335fa306126a9b37a..3dba83c273906005d2fbaae95e7adce007b707ac 100644 (file)
@@ -6131,6 +6131,45 @@ static int test_invalid_ctx_for_digest(void)
     return ret;
 }
 
+static int test_evp_cipher_negative_length(void)
+{
+    EVP_CIPHER_CTX *ctx = NULL;
+    EVP_CIPHER *cipher = NULL;
+    unsigned char key[16] = { 0 };
+    unsigned char iv[16] = { 0 };
+    unsigned char buffer[32] = { 0 };
+    int outl = 0;
+    int ret = 0;
+
+    if (!TEST_ptr(ctx = EVP_CIPHER_CTX_new()))
+        goto end;
+
+    if (!TEST_ptr(cipher = EVP_CIPHER_fetch(testctx, "AES-128-CBC", testpropq)))
+        goto end;
+
+    /* Initialize encryption context */
+    if (!TEST_int_eq(EVP_EncryptInit_ex2(ctx, cipher, key, iv, NULL), 1))
+        goto end;
+
+    /* Test EVP_EncryptUpdate with negative length - should fail */
+    if (!TEST_int_eq(EVP_EncryptUpdate(ctx, buffer, &outl, (unsigned char *)"test", -1), 0))
+        goto end;
+
+    /* Reinitialize for decryption */
+    if (!TEST_int_eq(EVP_DecryptInit_ex2(ctx, cipher, key, iv, NULL), 1))
+        goto end;
+
+    /* Test EVP_DecryptUpdate with negative length - should fail */
+    if (!TEST_int_eq(EVP_DecryptUpdate(ctx, buffer, &outl, (unsigned char *)"test", -1), 0))
+        goto end;
+
+    ret = 1;
+end:
+    EVP_CIPHER_free(cipher);
+    EVP_CIPHER_CTX_free(ctx);
+    return ret;
+}
+
 static int test_evp_cipher_pipeline(void)
 {
     OSSL_PROVIDER *fake_pipeline = NULL;
@@ -6869,6 +6908,8 @@ int setup_tests(void)
 
     ADD_TEST(test_invalid_ctx_for_digest);
 
+    ADD_TEST(test_evp_cipher_negative_length);
+
     ADD_TEST(test_evp_cipher_pipeline);
 
 #ifndef OPENSSL_NO_ML_KEM