Commit f9bdb61bbf for openssl.org

commit f9bdb61bbf54d8cedf0be5f9546162b6b975fc33
Author: Matt Caswell <matt@openssl.org>
Date:   Thu Dec 18 16:45:12 2025 +0000

    Remove some last remaining EVP_CIPHER related legacy paths

    There were some final remaining legacy paths that are now redundant and
    can be removed.

    Reviewed-by: Tomas Mraz <tomas@openssl.org>
    Reviewed-by: Neil Horman <nhorman@openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/29446)

diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c
index f5cefe207c..c04a4dc782 100644
--- a/crypto/evp/evp_enc.c
+++ b/crypto/evp/evp_enc.c
@@ -31,7 +31,7 @@ int EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *ctx)
         return 1;

     if (ctx->cipher == NULL || ctx->cipher->prov == NULL)
-        goto legacy;
+        return 1;

     if (ctx->algctx != NULL) {
         if (ctx->cipher->freectx != NULL)
@@ -44,21 +44,6 @@ int EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *ctx)
     ctx->iv_len = -1;

     return 1;
-
-    /* Remove legacy code below when legacy support is removed. */
-legacy:
-
-    if (ctx->cipher != NULL) {
-        if (ctx->cipher->cleanup && !ctx->cipher->cleanup(ctx))
-            return 0;
-        /* Cleanse cipher context data */
-        if (ctx->cipher_data && ctx->cipher->ctx_size)
-            OPENSSL_cleanse(ctx->cipher_data, ctx->cipher->ctx_size);
-    }
-    OPENSSL_free(ctx->cipher_data);
-    memset(ctx, 0, sizeof(*ctx));
-    ctx->iv_len = -1;
-    return 1;
 }

 EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void)
@@ -662,81 +647,6 @@ int ossl_is_partially_overlapping(const void *ptr1, const void *ptr2, int len)
     return overlapped;
 }

-static int evp_EncryptDecryptUpdate(EVP_CIPHER_CTX *ctx,
-    unsigned char *out, int *outl,
-    const unsigned char *in, int inl)
-{
-    int i, j, bl, cmpl = inl;
-
-    if (EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS))
-        cmpl = safe_div_round_up_int(cmpl, 8, NULL);
-
-    bl = ctx->cipher->block_size;
-
-    if (inl <= 0) {
-        *outl = 0;
-        return inl == 0;
-    }
-    if (ossl_is_partially_overlapping(out + ctx->buf_len, in, cmpl)) {
-        ERR_raise(ERR_LIB_EVP, EVP_R_PARTIALLY_OVERLAPPING);
-        return 0;
-    }
-
-    if (ctx->buf_len == 0 && (inl & (ctx->block_mask)) == 0) {
-        if (ctx->cipher->do_cipher(ctx, out, in, inl)) {
-            *outl = inl;
-            return 1;
-        } else {
-            *outl = 0;
-            return 0;
-        }
-    }
-    i = ctx->buf_len;
-    OPENSSL_assert(bl <= (int)sizeof(ctx->buf));
-    if (i != 0) {
-        if (bl - i > inl) {
-            memcpy(&(ctx->buf[i]), in, inl);
-            ctx->buf_len += inl;
-            *outl = 0;
-            return 1;
-        } else {
-            j = bl - i;
-
-            /*
-             * Once we've processed the first j bytes from in, the amount of
-             * data left that is a multiple of the block length is:
-             * (inl - j) & ~(bl - 1)
-             * We must ensure that this amount of data, plus the one block that
-             * we process from ctx->buf does not exceed INT_MAX
-             */
-            if (((inl - j) & ~(bl - 1)) > INT_MAX - bl) {
-                ERR_raise(ERR_LIB_EVP, EVP_R_OUTPUT_WOULD_OVERFLOW);
-                return 0;
-            }
-            memcpy(&(ctx->buf[i]), in, j);
-            inl -= j;
-            in += j;
-            if (!ctx->cipher->do_cipher(ctx, out, ctx->buf, bl))
-                return 0;
-            out += bl;
-            *outl = bl;
-        }
-    } else
-        *outl = 0;
-    i = inl & (bl - 1);
-    inl -= i;
-    if (inl > 0) {
-        if (!ctx->cipher->do_cipher(ctx, out, in, inl))
-            return 0;
-        *outl += inl;
-    }
-
-    if (i != 0)
-        memcpy(ctx->buf, &(in[inl]), i);
-    ctx->buf_len = i;
-    return 1;
-}
-
 int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
     const unsigned char *in, int inl)
 {
@@ -763,7 +673,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
     }

     if (ossl_unlikely(ctx->cipher->prov == NULL))
-        goto legacy;
+        return 0;

     blocksize = ctx->cipher->block_size;

@@ -785,11 +695,6 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
     }

     return ret;
-
-    /* Code below to be removed when legacy support is dropped. */
-legacy:
-
-    return evp_EncryptDecryptUpdate(ctx, out, outl, in, inl);
 }

 int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
@@ -1021,8 +926,10 @@ int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
         return 0;
     }

-    if (ctx->cipher->prov == NULL)
-        goto legacy;
+    if (ctx->cipher->prov == NULL) {
+        ERR_raise(ERR_LIB_EVP, EVP_R_CTRL_NOT_IMPLEMENTED);
+        return 0;
+    }

     switch (type) {
     case EVP_CTRL_SET_KEY_LENGTH:
@@ -1200,16 +1107,6 @@ int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
         ret = evp_do_ciph_ctx_setparams(ctx->cipher, ctx->algctx, params);
     else
         ret = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->algctx, params);
-    goto end;
-
-    /* Code below to be removed when legacy support is dropped. */
-legacy:
-    if (ctx->cipher->ctrl == NULL) {
-        ERR_raise(ERR_LIB_EVP, EVP_R_CTRL_NOT_IMPLEMENTED);
-        return 0;
-    }
-
-    ret = ctx->cipher->ctrl(ctx, type, arg, ptr);

 end:
     if (ret == EVP_CTRL_RET_UNSUPPORTED) {
diff --git a/crypto/evp/evp_lib.c b/crypto/evp/evp_lib.c
index 312452221d..f5a4d24e30 100644
--- a/crypto/evp/evp_lib.c
+++ b/crypto/evp/evp_lib.c
@@ -89,12 +89,7 @@ int evp_cipher_param_to_asn1_ex(EVP_CIPHER_CTX *c, ASN1_TYPE *type,

     cipher = c->cipher;
     /*
-     * For legacy implementations, we detect custom AlgorithmIdentifier
-     * parameter handling by checking if the function pointer
-     * cipher->set_asn1_parameters is set.  We know that this pointer
-     * is NULL for provided implementations.
-     *
-     * Otherwise, for any implementation, we check the flag
+     * For any implementation, we check the flag
      * EVP_CIPH_FLAG_CUSTOM_ASN1.  If it isn't set, we apply
      * default AI parameter extraction.
      *
@@ -104,9 +99,7 @@ int evp_cipher_param_to_asn1_ex(EVP_CIPHER_CTX *c, ASN1_TYPE *type,
      *
      * If none of the above applies, this operation is unsupported.
      */
-    if (cipher->set_asn1_parameters != NULL) {
-        ret = cipher->set_asn1_parameters(c, type);
-    } else if ((EVP_CIPHER_get_flags(cipher) & EVP_CIPH_FLAG_CUSTOM_ASN1) == 0) {
+    if ((EVP_CIPHER_get_flags(cipher) & EVP_CIPH_FLAG_CUSTOM_ASN1) == 0) {
         switch (EVP_CIPHER_get_mode(cipher)) {
         case EVP_CIPH_WRAP_MODE:
             if (EVP_CIPHER_is_a(cipher, SN_id_smime_alg_CMS3DESwrap))
@@ -160,12 +153,7 @@ int evp_cipher_asn1_to_param_ex(EVP_CIPHER_CTX *c, ASN1_TYPE *type,

     cipher = c->cipher;
     /*
-     * For legacy implementations, we detect custom AlgorithmIdentifier
-     * parameter handling by checking if there the function pointer
-     * cipher->get_asn1_parameters is set.  We know that this pointer
-     * is NULL for provided implementations.
-     *
-     * Otherwise, for any implementation, we check the flag
+     * For any implementation, we check the flag
      * EVP_CIPH_FLAG_CUSTOM_ASN1.  If it isn't set, we apply
      * default AI parameter creation.
      *
@@ -175,9 +163,7 @@ int evp_cipher_asn1_to_param_ex(EVP_CIPHER_CTX *c, ASN1_TYPE *type,
      *
      * If none of the above applies, this operation is unsupported.
      */
-    if (cipher->get_asn1_parameters != NULL) {
-        ret = cipher->get_asn1_parameters(c, type);
-    } else if ((EVP_CIPHER_get_flags(cipher) & EVP_CIPH_FLAG_CUSTOM_ASN1) == 0) {
+    if ((EVP_CIPHER_get_flags(cipher) & EVP_CIPH_FLAG_CUSTOM_ASN1) == 0) {
         switch (EVP_CIPHER_get_mode(cipher)) {
         case EVP_CIPH_WRAP_MODE:
             ret = 1;
@@ -381,48 +367,44 @@ int EVP_CIPHER_CTX_get_block_size(const EVP_CIPHER_CTX *ctx)

 int EVP_CIPHER_impl_ctx_size(const EVP_CIPHER *e)
 {
-    return e->ctx_size;
+    return 0;
 }

 int EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
     const unsigned char *in, unsigned int inl)
 {
-    if (ctx == NULL || ctx->cipher == NULL)
+    if (ctx == NULL || ctx->cipher == NULL || ctx->cipher->prov == NULL)
         return 0;

-    if (ctx->cipher->prov != NULL) {
-        /*
-         * If the provided implementation has a ccipher function, we use it,
-         * and translate its return value like this: 0 => -1, 1 => outlen
-         *
-         * Otherwise, we call the cupdate function if in != NULL, or cfinal
-         * if in == NULL.  Regardless of which, we return what we got.
-         */
-        int ret = -1;
-        size_t outl = 0;
-        size_t blocksize = EVP_CIPHER_CTX_get_block_size(ctx);
-
-        if (blocksize == 0)
-            return 0;
-
-        if (ctx->cipher->ccipher != NULL)
-            ret = ctx->cipher->ccipher(ctx->algctx, out, &outl,
-                      inl + (blocksize == 1 ? 0 : blocksize),
-                      in, (size_t)inl)
-                ? (int)outl
-                : -1;
-        else if (in != NULL)
-            ret = ctx->cipher->cupdate(ctx->algctx, out, &outl,
-                inl + (blocksize == 1 ? 0 : blocksize),
-                in, (size_t)inl);
-        else
-            ret = ctx->cipher->cfinal(ctx->algctx, out, &outl,
-                blocksize == 1 ? 0 : blocksize);
-
-        return ret;
-    }
+    /*
+     * If the provided implementation has a ccipher function, we use it,
+     * and translate its return value like this: 0 => -1, 1 => outlen
+     *
+     * Otherwise, we call the cupdate function if in != NULL, or cfinal
+     * if in == NULL.  Regardless of which, we return what we got.
+     */
+    int ret = -1;
+    size_t outl = 0;
+    size_t blocksize = EVP_CIPHER_CTX_get_block_size(ctx);

-    return ctx->cipher->do_cipher(ctx, out, in, inl);
+    if (blocksize == 0)
+        return 0;
+
+    if (ctx->cipher->ccipher != NULL)
+        ret = ctx->cipher->ccipher(ctx->algctx, out, &outl,
+                  inl + (blocksize == 1 ? 0 : blocksize),
+                  in, (size_t)inl)
+            ? (int)outl
+            : -1;
+    else if (in != NULL)
+        ret = ctx->cipher->cupdate(ctx->algctx, out, &outl,
+            inl + (blocksize == 1 ? 0 : blocksize),
+            in, (size_t)inl);
+    else
+        ret = ctx->cipher->cfinal(ctx->algctx, out, &outl,
+            blocksize == 1 ? 0 : blocksize);
+
+    return ret;
 }

 #ifndef OPENSSL_NO_DEPRECATED_3_0