Remove support for custom cipher methods

Custom cipher methods are considered legacy and have been deprecated
since 3.0. With the removal of ENGINEs they become a lot less useful
and add significant complexity to the code. We should therefore remove
them in 4.0.

Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/29299)
This commit is contained in:
Matt Caswell
2025-12-03 10:38:56 +00:00
committed by Tomas Mraz
parent 2d5c98c30a
commit 441bf727d0
8 changed files with 89 additions and 912 deletions

View File

@@ -1480,19 +1480,6 @@ int ossl_cms_RecipientInfo_wrap_init(CMS_RecipientInfo *ri,
ERR_raise(ERR_LIB_CMS, CMS_R_INVALID_KEY_LENGTH);
return 0;
}
if ((EVP_CIPHER_get_flags(cipher) & EVP_CIPH_FLAG_GET_WRAP_CIPHER) != 0) {
ret = EVP_CIPHER_meth_get_ctrl(cipher)(NULL, EVP_CTRL_GET_WRAP_CIPHER,
0, &kekcipher);
if (ret <= 0)
return 0;
if (kekcipher != NULL) {
if (EVP_CIPHER_get_mode(kekcipher) != EVP_CIPH_WRAP_MODE)
return 0;
kekcipher_name = EVP_CIPHER_get0_name(kekcipher);
goto enc;
}
}
/*
* Pick a cipher based on content encryption cipher. If it is DES3 use
@@ -1509,7 +1496,7 @@ int ossl_cms_RecipientInfo_wrap_init(CMS_RecipientInfo *ri,
kekcipher_name = SN_id_aes192_wrap;
else
kekcipher_name = SN_id_aes256_wrap;
enc:
fetched_kekcipher = EVP_CIPHER_fetch(ossl_cms_ctx_get0_libctx(cms_ctx),
kekcipher_name,
ossl_cms_ctx_get0_propq(cms_ctx));

View File

@@ -18,7 +18,7 @@ SOURCE[../../libcrypto]=$COMMON\
e_aes_cbc_hmac_sha1.c e_aes_cbc_hmac_sha256.c e_rc4_hmac_md5.c \
e_chacha20_poly1305.c \
legacy_sha.c ctrl_params_translate.c \
cmeth_lib.c m_sigver.c
m_sigver.c
# Diverse type specific ctrl functions. They are kinda sorta legacy, kinda
# sorta not.

View File

@@ -1,200 +0,0 @@
/*
* Copyright 2015-2023 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
/*
* EVP _meth_ APIs are deprecated for public use, but still ok for
* internal use.
*/
#include "internal/deprecated.h"
#include <string.h>
#include <openssl/evp.h>
#include "crypto/evp.h"
#include "internal/provider.h"
#include "evp_local.h"
EVP_CIPHER *EVP_CIPHER_meth_new(int cipher_type, int block_size, int key_len)
{
EVP_CIPHER *cipher = evp_cipher_new();
if (cipher != NULL) {
cipher->nid = cipher_type;
cipher->block_size = block_size;
cipher->key_len = key_len;
cipher->origin = EVP_ORIG_METH;
}
return cipher;
}
EVP_CIPHER *EVP_CIPHER_meth_dup(const EVP_CIPHER *cipher)
{
EVP_CIPHER *to = NULL;
/*
* Non-legacy EVP_CIPHERs can't be duplicated like this.
* Use EVP_CIPHER_up_ref() instead.
*/
if (cipher->prov != NULL)
return NULL;
if ((to = EVP_CIPHER_meth_new(cipher->nid, cipher->block_size,
cipher->key_len))
!= NULL) {
CRYPTO_REF_COUNT refcnt = to->refcnt;
memcpy(to, cipher, sizeof(*to));
to->refcnt = refcnt;
to->origin = EVP_ORIG_METH;
}
return to;
}
void EVP_CIPHER_meth_free(EVP_CIPHER *cipher)
{
if (cipher == NULL || cipher->origin != EVP_ORIG_METH)
return;
evp_cipher_free_int(cipher);
}
int EVP_CIPHER_meth_set_iv_length(EVP_CIPHER *cipher, int iv_len)
{
if (cipher->iv_len != 0)
return 0;
cipher->iv_len = iv_len;
return 1;
}
int EVP_CIPHER_meth_set_flags(EVP_CIPHER *cipher, unsigned long flags)
{
if (cipher->flags != 0)
return 0;
cipher->flags = flags;
return 1;
}
int EVP_CIPHER_meth_set_impl_ctx_size(EVP_CIPHER *cipher, int ctx_size)
{
if (cipher->ctx_size != 0)
return 0;
cipher->ctx_size = ctx_size;
return 1;
}
int EVP_CIPHER_meth_set_init(EVP_CIPHER *cipher,
int (*init)(EVP_CIPHER_CTX *ctx,
const unsigned char *key,
const unsigned char *iv,
int enc))
{
if (cipher->init != NULL)
return 0;
cipher->init = init;
return 1;
}
int EVP_CIPHER_meth_set_do_cipher(EVP_CIPHER *cipher,
int (*do_cipher)(EVP_CIPHER_CTX *ctx,
unsigned char *out,
const unsigned char *in,
size_t inl))
{
if (cipher->do_cipher != NULL)
return 0;
cipher->do_cipher = do_cipher;
return 1;
}
int EVP_CIPHER_meth_set_cleanup(EVP_CIPHER *cipher,
int (*cleanup)(EVP_CIPHER_CTX *))
{
if (cipher->cleanup != NULL)
return 0;
cipher->cleanup = cleanup;
return 1;
}
int EVP_CIPHER_meth_set_set_asn1_params(EVP_CIPHER *cipher,
int (*set_asn1_parameters)(EVP_CIPHER_CTX *,
ASN1_TYPE *))
{
if (cipher->set_asn1_parameters != NULL)
return 0;
cipher->set_asn1_parameters = set_asn1_parameters;
return 1;
}
int EVP_CIPHER_meth_set_get_asn1_params(EVP_CIPHER *cipher,
int (*get_asn1_parameters)(EVP_CIPHER_CTX *,
ASN1_TYPE *))
{
if (cipher->get_asn1_parameters != NULL)
return 0;
cipher->get_asn1_parameters = get_asn1_parameters;
return 1;
}
int EVP_CIPHER_meth_set_ctrl(EVP_CIPHER *cipher,
int (*ctrl)(EVP_CIPHER_CTX *, int type,
int arg, void *ptr))
{
if (cipher->ctrl != NULL)
return 0;
cipher->ctrl = ctrl;
return 1;
}
int (*EVP_CIPHER_meth_get_init(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *ctx,
const unsigned char *key,
const unsigned char *iv,
int enc)
{
return cipher->init;
}
int (*EVP_CIPHER_meth_get_do_cipher(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *ctx,
unsigned char *out,
const unsigned char *in,
size_t inl)
{
return cipher->do_cipher;
}
int (*EVP_CIPHER_meth_get_cleanup(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *)
{
return cipher->cleanup;
}
int (*EVP_CIPHER_meth_get_set_asn1_params(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *,
ASN1_TYPE *)
{
return cipher->set_asn1_parameters;
}
int (*EVP_CIPHER_meth_get_get_asn1_params(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *,
ASN1_TYPE *)
{
return cipher->get_asn1_parameters;
}
int (*EVP_CIPHER_meth_get_ctrl(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *,
int type, int arg,
void *ptr)
{
return cipher->ctrl;
}

View File

@@ -88,8 +88,6 @@ static int evp_cipher_init_internal(EVP_CIPHER_CTX *ctx,
uint8_t is_pipeline,
const OSSL_PARAM params[])
{
int n;
/*
* enc == 1 means we are encrypting.
* enc == 0 means we are decrypting.
@@ -108,35 +106,6 @@ static int evp_cipher_init_internal(EVP_CIPHER_CTX *ctx,
return 0;
}
/* Code below to be removed when legacy support is dropped. */
if (is_pipeline)
goto nonlegacy;
/*
* If there are engines involved then we should use legacy handling for now.
*/
if ((cipher != NULL && cipher->origin == EVP_ORIG_METH)
|| (cipher == NULL && ctx->cipher != NULL
&& ctx->cipher->origin == EVP_ORIG_METH)) {
if (ctx->cipher == ctx->fetched_cipher)
ctx->cipher = NULL;
EVP_CIPHER_free(ctx->fetched_cipher);
ctx->fetched_cipher = NULL;
goto legacy;
}
/*
* Ensure a context left lying around from last time is cleared
* (legacy code)
*/
if (cipher != NULL && ctx->cipher != NULL) {
if (ctx->cipher->cleanup != NULL && !ctx->cipher->cleanup(ctx))
return 0;
OPENSSL_clear_free(ctx->cipher_data, ctx->cipher->ctx_size);
ctx->cipher_data = NULL;
}
/* Start of non-legacy code below */
nonlegacy:
/* Ensure a context left lying around from last time is cleared */
if (cipher != NULL && ctx->cipher != NULL) {
unsigned long flags = ctx->flags;
@@ -298,111 +267,6 @@ nonlegacy:
iv == NULL ? 0
: EVP_CIPHER_CTX_get_iv_length(ctx),
params);
/* Code below to be removed when legacy support is dropped. */
legacy:
if (cipher != NULL) {
/*
* Ensure a context left lying around from last time is cleared (we
* previously attempted to avoid this if the same ENGINE and
* EVP_CIPHER could be used).
*/
if (ctx->cipher) {
unsigned long flags = ctx->flags;
EVP_CIPHER_CTX_reset(ctx);
/* Restore encrypt and flags */
ctx->encrypt = enc;
ctx->flags = flags;
}
ctx->cipher = cipher;
if (ctx->cipher->ctx_size) {
ctx->cipher_data = OPENSSL_zalloc(ctx->cipher->ctx_size);
if (ctx->cipher_data == NULL) {
ctx->cipher = NULL;
return 0;
}
} else {
ctx->cipher_data = NULL;
}
ctx->key_len = cipher->key_len;
/* Preserve wrap enable flag, zero everything else */
ctx->flags &= EVP_CIPHER_CTX_FLAG_WRAP_ALLOW;
if (ctx->cipher->flags & EVP_CIPH_CTRL_INIT) {
if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL) <= 0) {
ctx->cipher = NULL;
ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
return 0;
}
}
}
if (ctx->cipher == NULL)
return 0;
/* we assume block size is a power of 2 in *cryptUpdate */
OPENSSL_assert(ctx->cipher->block_size == 1
|| ctx->cipher->block_size == 8
|| ctx->cipher->block_size == 16);
if (!(ctx->flags & EVP_CIPHER_CTX_FLAG_WRAP_ALLOW)
&& EVP_CIPHER_CTX_get_mode(ctx) == EVP_CIPH_WRAP_MODE) {
ERR_raise(ERR_LIB_EVP, EVP_R_WRAP_MODE_NOT_ALLOWED);
return 0;
}
if ((EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(ctx))
& EVP_CIPH_CUSTOM_IV)
== 0) {
switch (EVP_CIPHER_CTX_get_mode(ctx)) {
case EVP_CIPH_STREAM_CIPHER:
case EVP_CIPH_ECB_MODE:
break;
case EVP_CIPH_CFB_MODE:
case EVP_CIPH_OFB_MODE:
ctx->num = 0;
/* fall-through */
case EVP_CIPH_CBC_MODE:
n = EVP_CIPHER_CTX_get_iv_length(ctx);
if (n < 0 || n > (int)sizeof(ctx->iv)) {
ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_IV_LENGTH);
return 0;
}
if (iv != NULL)
memcpy(ctx->oiv, iv, n);
memcpy(ctx->iv, ctx->oiv, n);
break;
case EVP_CIPH_CTR_MODE:
ctx->num = 0;
/* Don't reuse IV for CTR mode */
if (iv != NULL) {
n = EVP_CIPHER_CTX_get_iv_length(ctx);
if (n <= 0 || n > (int)sizeof(ctx->iv)) {
ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_IV_LENGTH);
return 0;
}
memcpy(ctx->iv, iv, n);
}
break;
default:
return 0;
}
}
if (key != NULL || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) {
if (!ctx->cipher->init(ctx, key, iv, enc))
return 0;
}
ctx->buf_len = 0;
ctx->final_used = 0;
ctx->block_mask = ctx->cipher->block_size - 1;
return 1;
}
/*
@@ -432,26 +296,6 @@ static int evp_cipher_init_skey_internal(EVP_CIPHER_CTX *ctx,
return 0;
}
/*
* If there are engines involved then we throw an error
*/
if ((cipher != NULL && cipher->origin == EVP_ORIG_METH)
|| (cipher == NULL && ctx->cipher != NULL
&& ctx->cipher->origin == EVP_ORIG_METH)) {
ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
return 0;
}
/*
* Ensure a context left lying around from last time is cleared
* (legacy code)
*/
if (cipher != NULL && ctx->cipher != NULL) {
if (ctx->cipher->cleanup != NULL && !ctx->cipher->cleanup(ctx))
return 0;
OPENSSL_clear_free(ctx->cipher_data, ctx->cipher->ctx_size);
ctx->cipher_data = NULL;
}
/* Ensure a context left lying around from last time is cleared */
if (cipher != NULL && ctx->cipher != NULL) {
unsigned long flags = ctx->flags;
@@ -829,21 +673,6 @@ static int evp_EncryptDecryptUpdate(EVP_CIPHER_CTX *ctx,
bl = ctx->cipher->block_size;
if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
/* If block size > 1 then the cipher will have to do this check */
if (bl == 1 && ossl_is_partially_overlapping(out, in, cmpl)) {
ERR_raise(ERR_LIB_EVP, EVP_R_PARTIALLY_OVERLAPPING);
return 0;
}
i = ctx->cipher->do_cipher(ctx, out, in, inl);
if (i < 0)
return 0;
else
*outl = i;
return 1;
}
if (inl <= 0) {
*outl = 0;
return inl == 0;
@@ -972,8 +801,7 @@ int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
{
int n, ret;
unsigned int i, b, bl;
int ret;
size_t soutl;
int blocksize;
@@ -994,8 +822,10 @@ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
ERR_raise(ERR_LIB_EVP, EVP_R_NO_CIPHER_SET);
return 0;
}
if (ctx->cipher->prov == NULL)
goto legacy;
if (ctx->cipher->prov == NULL) {
ERR_raise(ERR_LIB_EVP, EVP_R_NO_CIPHER_SET);
return 0;
}
blocksize = EVP_CIPHER_CTX_get_block_size(ctx);
@@ -1016,51 +846,12 @@ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
}
return ret;
/* Code below to be removed when legacy support is dropped. */
legacy:
if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
ret = ctx->cipher->do_cipher(ctx, out, NULL, 0);
if (ret < 0)
return 0;
else
*outl = ret;
return 1;
}
b = ctx->cipher->block_size;
OPENSSL_assert(b <= sizeof(ctx->buf));
if (b == 1) {
*outl = 0;
return 1;
}
bl = ctx->buf_len;
if (ctx->flags & EVP_CIPH_NO_PADDING) {
if (bl) {
ERR_raise(ERR_LIB_EVP, EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
return 0;
}
*outl = 0;
return 1;
}
n = b - bl;
for (i = bl; i < b; i++)
ctx->buf[i] = n;
ret = ctx->cipher->do_cipher(ctx, out, ctx->buf, b);
if (ret)
*outl = b;
return ret;
}
int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
const unsigned char *in, int inl)
{
int fix_len, cmpl = inl, ret;
unsigned int b;
int ret;
size_t soutl, inl_ = (size_t)inl;
int blocksize;
@@ -1081,8 +872,10 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
ERR_raise(ERR_LIB_EVP, EVP_R_NO_CIPHER_SET);
return 0;
}
if (ossl_unlikely(ctx->cipher->prov == NULL))
goto legacy;
if (ossl_unlikely(ctx->cipher->prov == NULL)) {
ERR_raise(ERR_LIB_EVP, EVP_R_NO_CIPHER_SET);
return 0;
}
blocksize = EVP_CIPHER_CTX_get_block_size(ctx);
@@ -1103,84 +896,6 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
}
return ret;
/* Code below to be removed when legacy support is dropped. */
legacy:
b = ctx->cipher->block_size;
if (EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS))
cmpl = safe_div_round_up_int(cmpl, 8, NULL);
if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
if (b == 1 && ossl_is_partially_overlapping(out, in, cmpl)) {
ERR_raise(ERR_LIB_EVP, EVP_R_PARTIALLY_OVERLAPPING);
return 0;
}
fix_len = ctx->cipher->do_cipher(ctx, out, in, inl);
if (fix_len < 0) {
*outl = 0;
return 0;
} else
*outl = fix_len;
return 1;
}
if (inl <= 0) {
*outl = 0;
return inl == 0;
}
if (ctx->flags & EVP_CIPH_NO_PADDING)
return evp_EncryptDecryptUpdate(ctx, out, outl, in, inl);
OPENSSL_assert(b <= sizeof(ctx->final));
if (ctx->final_used) {
/* see comment about PTRDIFF_T comparison above */
if (((PTRDIFF_T)out == (PTRDIFF_T)in)
|| ossl_is_partially_overlapping(out, in, b)) {
ERR_raise(ERR_LIB_EVP, EVP_R_PARTIALLY_OVERLAPPING);
return 0;
}
/*
* final_used is only ever set if buf_len is 0. Therefore the maximum
* length output we will ever see from evp_EncryptDecryptUpdate is
* the maximum multiple of the block length that is <= inl, or just:
* inl & ~(b - 1)
* Since final_used has been set then the final output length is:
* (inl & ~(b - 1)) + b
* This must never exceed INT_MAX
*/
if ((inl & ~(b - 1)) > INT_MAX - b) {
ERR_raise(ERR_LIB_EVP, EVP_R_OUTPUT_WOULD_OVERFLOW);
return 0;
}
memcpy(out, ctx->final, b);
out += b;
fix_len = 1;
} else
fix_len = 0;
if (!evp_EncryptDecryptUpdate(ctx, out, outl, in, inl))
return 0;
/*
* if we have 'decrypted' a multiple of block size, make sure we have a
* copy of this last block
*/
if (b > 1 && !ctx->buf_len) {
*outl -= b;
ctx->final_used = 1;
memcpy(ctx->final, &out[*outl], b);
} else
ctx->final_used = 0;
if (fix_len)
*outl += b;
return 1;
}
int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
@@ -1192,8 +907,6 @@ int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
{
int i, n;
unsigned int b;
size_t soutl;
int ret;
int blocksize;
@@ -1216,8 +929,10 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
return 0;
}
if (ctx->cipher->prov == NULL)
goto legacy;
if (ctx->cipher->prov == NULL) {
ERR_raise(ERR_LIB_EVP, EVP_R_NO_CIPHER_SET);
return 0;
}
blocksize = EVP_CIPHER_CTX_get_block_size(ctx);
@@ -1238,103 +953,38 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
}
return ret;
/* Code below to be removed when legacy support is dropped. */
legacy:
*outl = 0;
if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
i = ctx->cipher->do_cipher(ctx, out, NULL, 0);
if (i < 0)
return 0;
else
*outl = i;
return 1;
}
b = ctx->cipher->block_size;
if (ctx->flags & EVP_CIPH_NO_PADDING) {
if (ctx->buf_len) {
ERR_raise(ERR_LIB_EVP, EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
return 0;
}
*outl = 0;
return 1;
}
if (b > 1) {
if (ctx->buf_len || !ctx->final_used) {
ERR_raise(ERR_LIB_EVP, EVP_R_WRONG_FINAL_BLOCK_LENGTH);
return 0;
}
OPENSSL_assert(b <= sizeof(ctx->final));
/*
* The following assumes that the ciphertext has been authenticated.
* Otherwise it provides a padding oracle.
*/
n = ctx->final[b - 1];
if (n == 0 || n > (int)b) {
ERR_raise(ERR_LIB_EVP, EVP_R_BAD_DECRYPT);
return 0;
}
for (i = 0; i < n; i++) {
if (ctx->final[--b] != n) {
ERR_raise(ERR_LIB_EVP, EVP_R_BAD_DECRYPT);
return 0;
}
}
n = ctx->cipher->block_size - n;
for (i = 0; i < n; i++)
out[i] = ctx->final[i];
*outl = n;
}
return 1;
}
int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen)
{
if (c->cipher->prov != NULL) {
int ok;
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
size_t len;
int ok;
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
size_t len;
if (EVP_CIPHER_CTX_get_key_length(c) == keylen)
return 1;
/* Check the cipher actually understands this parameter */
if (OSSL_PARAM_locate_const(EVP_CIPHER_settable_ctx_params(c->cipher),
OSSL_CIPHER_PARAM_KEYLEN)
== NULL) {
ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_KEY_LENGTH);
return 0;
}
params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_KEYLEN, &len);
if (!OSSL_PARAM_set_int(params, keylen))
return 0;
ok = evp_do_ciph_ctx_setparams(c->cipher, c->algctx, params);
if (ok <= 0)
return 0;
c->key_len = keylen;
return 1;
if (c->cipher->prov == NULL) {
ERR_raise(ERR_LIB_EVP, EVP_R_CIPHER_PARAMETER_ERROR);
return 0;
}
/* Code below to be removed when legacy support is dropped. */
/*
* Note there have never been any built-in ciphers that define this flag
* since it was first introduced.
*/
if (c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH)
return EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_KEY_LENGTH, keylen, NULL);
if (EVP_CIPHER_CTX_get_key_length(c) == keylen)
return 1;
if ((keylen > 0) && (c->cipher->flags & EVP_CIPH_VARIABLE_LENGTH)) {
c->key_len = keylen;
return 1;
/* Check the cipher actually understands this parameter */
if (OSSL_PARAM_locate_const(EVP_CIPHER_settable_ctx_params(c->cipher),
OSSL_CIPHER_PARAM_KEYLEN)
== NULL) {
ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_KEY_LENGTH);
return 0;
}
ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_KEY_LENGTH);
return 0;
params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_KEYLEN, &len);
if (!OSSL_PARAM_set_int(params, keylen))
return 0;
ok = evp_do_ciph_ctx_setparams(c->cipher, c->algctx, params);
if (ok <= 0)
return 0;
c->key_len = keylen;
return 1;
}
int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad)
@@ -1712,8 +1362,10 @@ int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in)
return 0;
}
if (in->cipher->prov == NULL)
goto legacy;
if (in->cipher->prov == NULL) {
ERR_raise(ERR_LIB_EVP, EVP_R_INPUT_NOT_INITIALIZED);
return 0;
}
if (in->cipher->dupctx == NULL) {
ERR_raise(ERR_LIB_EVP, EVP_R_NOT_ABLE_TO_COPY_CTX);
@@ -1737,29 +1389,6 @@ int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in)
}
return 1;
/* Code below to be removed when legacy support is dropped. */
legacy:
EVP_CIPHER_CTX_reset(out);
memcpy(out, in, sizeof(*out));
if (in->cipher_data && in->cipher->ctx_size) {
out->cipher_data = OPENSSL_malloc(in->cipher->ctx_size);
if (out->cipher_data == NULL) {
out->cipher = NULL;
return 0;
}
memcpy(out->cipher_data, in->cipher_data, in->cipher->ctx_size);
}
if (in->cipher->flags & EVP_CIPH_CUSTOM_COPY)
if (!in->cipher->ctrl((EVP_CIPHER_CTX *)in, EVP_CTRL_COPY, 0, out)) {
out->cipher = NULL;
ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
return 0;
}
return 1;
}
EVP_CIPHER *evp_cipher_new(void)

View File

@@ -246,63 +246,6 @@ int (*EVP_MD_meth_get_ctrl(const EVP_MD *md))(EVP_MD_CTX *ctx, int cmd,
#define EVP_MD_CTX_FLAG_FINALISE 0x0200
/* NOTE: 0x0400 and 0x0800 are reserved for internal usage */
#ifndef OPENSSL_NO_DEPRECATED_3_0
OSSL_DEPRECATEDIN_3_0
EVP_CIPHER *EVP_CIPHER_meth_new(int cipher_type, int block_size, int key_len);
OSSL_DEPRECATEDIN_3_0
EVP_CIPHER *EVP_CIPHER_meth_dup(const EVP_CIPHER *cipher);
OSSL_DEPRECATEDIN_3_0
void EVP_CIPHER_meth_free(EVP_CIPHER *cipher);
OSSL_DEPRECATEDIN_3_0
int EVP_CIPHER_meth_set_iv_length(EVP_CIPHER *cipher, int iv_len);
OSSL_DEPRECATEDIN_3_0
int EVP_CIPHER_meth_set_flags(EVP_CIPHER *cipher, unsigned long flags);
OSSL_DEPRECATEDIN_3_0
int EVP_CIPHER_meth_set_impl_ctx_size(EVP_CIPHER *cipher, int ctx_size);
OSSL_DEPRECATEDIN_3_0
int EVP_CIPHER_meth_set_init(EVP_CIPHER *cipher,
int (*init)(EVP_CIPHER_CTX *ctx,
const unsigned char *key,
const unsigned char *iv,
int enc));
OSSL_DEPRECATEDIN_3_0
int EVP_CIPHER_meth_set_do_cipher(EVP_CIPHER *cipher,
int (*do_cipher)(EVP_CIPHER_CTX *ctx,
unsigned char *out,
const unsigned char *in,
size_t inl));
OSSL_DEPRECATEDIN_3_0
int EVP_CIPHER_meth_set_cleanup(EVP_CIPHER *cipher,
int (*cleanup)(EVP_CIPHER_CTX *));
OSSL_DEPRECATEDIN_3_0
int EVP_CIPHER_meth_set_set_asn1_params(EVP_CIPHER *cipher,
int (*set_asn1_parameters)(EVP_CIPHER_CTX *,
ASN1_TYPE *));
OSSL_DEPRECATEDIN_3_0
int EVP_CIPHER_meth_set_get_asn1_params(EVP_CIPHER *cipher,
int (*get_asn1_parameters)(EVP_CIPHER_CTX *,
ASN1_TYPE *));
OSSL_DEPRECATEDIN_3_0
int EVP_CIPHER_meth_set_ctrl(EVP_CIPHER *cipher,
int (*ctrl)(EVP_CIPHER_CTX *, int type,
int arg, void *ptr));
OSSL_DEPRECATEDIN_3_0 int (*EVP_CIPHER_meth_get_init(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *ctx,
const unsigned char *key,
const unsigned char *iv,
int enc);
OSSL_DEPRECATEDIN_3_0 int (*EVP_CIPHER_meth_get_do_cipher(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *ctx,
unsigned char *out,
const unsigned char *in,
size_t inl);
OSSL_DEPRECATEDIN_3_0 int (*EVP_CIPHER_meth_get_cleanup(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *);
OSSL_DEPRECATEDIN_3_0 int (*EVP_CIPHER_meth_get_set_asn1_params(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *,
ASN1_TYPE *);
OSSL_DEPRECATEDIN_3_0 int (*EVP_CIPHER_meth_get_get_asn1_params(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *,
ASN1_TYPE *);
OSSL_DEPRECATEDIN_3_0 int (*EVP_CIPHER_meth_get_ctrl(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *, int type,
int arg, void *ptr);
#endif
/* Values for cipher flags */
/* Modes for ciphers */

View File

@@ -186,10 +186,10 @@ static int tls1_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs,
size_t reclen[SSL_MAX_PIPELINES];
unsigned char buf[SSL_MAX_PIPELINES][EVP_AEAD_TLS1_AAD_LEN];
unsigned char *data[SSL_MAX_PIPELINES];
int pad = 0, tmpr, provided;
size_t bs, ctr, padnum, loop;
unsigned char padval;
int pad = 0;
size_t bs, ctr;
const EVP_CIPHER *enc;
int outlen;
if (n_recs == 0) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
@@ -240,8 +240,6 @@ static int tls1_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs,
return 0;
}
provided = (EVP_CIPHER_get0_provider(enc) != NULL);
bs = EVP_CIPHER_get_block_size(EVP_CIPHER_CTX_get0_cipher(ds));
if (bs == 0) {
@@ -301,25 +299,6 @@ static int tls1_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs,
reclen[ctr] += pad;
recs[ctr].length += pad;
}
} else if ((bs != 1) && sending && !provided) {
/*
* We only do this for legacy ciphers. Provided ciphers add the
* padding on the provider side.
*/
padnum = bs - (reclen[ctr] % bs);
/* Add weird padding of up to 256 bytes */
if (padnum > MAX_PADDING) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
/* we need to add 'padnum' padding bytes of value padval */
padval = (unsigned char)(padnum - 1);
for (loop = reclen[ctr]; loop < reclen[ctr] + padnum; loop++)
recs[ctr].input[loop] = padval;
reclen[ctr] += padnum;
recs[ctr].length += padnum;
}
if (!sending) {
@@ -375,112 +354,56 @@ static int tls1_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs,
}
}
if (provided) {
int outlen;
/* Provided cipher - we do not support pipelining on this path */
if (n_recs > 1) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
/* Provided cipher - we do not support pipelining on this path */
if (n_recs > 1) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
if (!EVP_CipherUpdate(ds, recs[0].data, &outlen, recs[0].input,
(unsigned int)reclen[0]))
return 0;
recs[0].length = outlen;
/*
* The length returned from EVP_CipherUpdate above is the actual
* payload length. We need to adjust the data/input ptr to skip over
* any explicit IV
*/
if (!sending) {
if (EVP_CIPHER_get_mode(enc) == EVP_CIPH_GCM_MODE) {
recs[0].data += EVP_GCM_TLS_EXPLICIT_IV_LEN;
recs[0].input += EVP_GCM_TLS_EXPLICIT_IV_LEN;
} else if (EVP_CIPHER_get_mode(enc) == EVP_CIPH_CCM_MODE) {
recs[0].data += EVP_CCM_TLS_EXPLICIT_IV_LEN;
recs[0].input += EVP_CCM_TLS_EXPLICIT_IV_LEN;
} else if (bs != 1 && RLAYER_USE_EXPLICIT_IV(rl)) {
recs[0].data += bs;
recs[0].input += bs;
recs[0].orig_len -= bs;
}
if (!EVP_CipherUpdate(ds, recs[0].data, &outlen, recs[0].input,
(unsigned int)reclen[0]))
return 0;
recs[0].length = outlen;
/* Now get a pointer to the MAC (if applicable) */
if (macs != NULL) {
OSSL_PARAM params[2], *p = params;
/*
* The length returned from EVP_CipherUpdate above is the actual
* payload length. We need to adjust the data/input ptr to skip over
* any explicit IV
*/
if (!sending) {
if (EVP_CIPHER_get_mode(enc) == EVP_CIPH_GCM_MODE) {
recs[0].data += EVP_GCM_TLS_EXPLICIT_IV_LEN;
recs[0].input += EVP_GCM_TLS_EXPLICIT_IV_LEN;
} else if (EVP_CIPHER_get_mode(enc) == EVP_CIPH_CCM_MODE) {
recs[0].data += EVP_CCM_TLS_EXPLICIT_IV_LEN;
recs[0].input += EVP_CCM_TLS_EXPLICIT_IV_LEN;
} else if (bs != 1 && RLAYER_USE_EXPLICIT_IV(rl)) {
recs[0].data += bs;
recs[0].input += bs;
recs[0].orig_len -= bs;
}
/* Get the MAC */
macs[0].alloced = 0;
/* Now get a pointer to the MAC (if applicable) */
if (macs != NULL) {
OSSL_PARAM params[2], *p = params;
*p++ = OSSL_PARAM_construct_octet_ptr(OSSL_CIPHER_PARAM_TLS_MAC,
(void **)&macs[0].mac,
macsize);
*p = OSSL_PARAM_construct_end();
/* Get the MAC */
macs[0].alloced = 0;
*p++ = OSSL_PARAM_construct_octet_ptr(OSSL_CIPHER_PARAM_TLS_MAC,
(void **)&macs[0].mac,
macsize);
*p = OSSL_PARAM_construct_end();
if (!EVP_CIPHER_CTX_get_params(ds, params)) {
/* Shouldn't normally happen */
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR,
ERR_R_INTERNAL_ERROR);
return 0;
}
}
}
} else {
/* Legacy cipher */
tmpr = EVP_Cipher(ds, recs[0].data, recs[0].input,
(unsigned int)reclen[0]);
if ((EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(ds))
& EVP_CIPH_FLAG_CUSTOM_CIPHER)
!= 0
? (tmpr < 0)
: (tmpr == 0)) {
/* AEAD can fail to verify MAC */
return 0;
}
if (!sending) {
for (ctr = 0; ctr < n_recs; ctr++) {
/* Adjust the record to remove the explicit IV/MAC/Tag */
if (EVP_CIPHER_get_mode(enc) == EVP_CIPH_GCM_MODE) {
recs[ctr].data += EVP_GCM_TLS_EXPLICIT_IV_LEN;
recs[ctr].input += EVP_GCM_TLS_EXPLICIT_IV_LEN;
recs[ctr].length -= EVP_GCM_TLS_EXPLICIT_IV_LEN;
} else if (EVP_CIPHER_get_mode(enc) == EVP_CIPH_CCM_MODE) {
recs[ctr].data += EVP_CCM_TLS_EXPLICIT_IV_LEN;
recs[ctr].input += EVP_CCM_TLS_EXPLICIT_IV_LEN;
recs[ctr].length -= EVP_CCM_TLS_EXPLICIT_IV_LEN;
} else if (bs != 1 && RLAYER_USE_EXPLICIT_IV(rl)) {
if (recs[ctr].length < bs)
return 0;
recs[ctr].data += bs;
recs[ctr].input += bs;
recs[ctr].length -= bs;
recs[ctr].orig_len -= bs;
}
/*
* If using Mac-then-encrypt, then this will succeed but
* with a random MAC if padding is invalid
*/
if (!tls1_cbc_remove_padding_and_mac(&recs[ctr].length,
recs[ctr].orig_len,
recs[ctr].data,
(macs != NULL) ? &macs[ctr].mac : NULL,
(macs != NULL) ? &macs[ctr].alloced
: NULL,
bs,
pad ? (size_t)pad : macsize,
(EVP_CIPHER_get_flags(enc)
& EVP_CIPH_FLAG_AEAD_CIPHER)
!= 0,
rl->libctx))
return 0;
if (!EVP_CIPHER_CTX_get_params(ds, params)) {
/* Shouldn't normally happen */
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR,
ERR_R_INTERNAL_ERROR);
return 0;
}
}
}
return 1;
}

View File

@@ -5992,20 +5992,18 @@ err:
return testresult;
}
static int test_evp_md_cipher_meth(void)
static int test_evp_md_meth(void)
{
EVP_MD *md = EVP_MD_meth_dup(EVP_sha256());
EVP_CIPHER *ciph = EVP_CIPHER_meth_dup(EVP_aes_128_cbc());
int testresult = 0;
if (!TEST_ptr(md) || !TEST_ptr(ciph))
if (!TEST_ptr(md))
goto err;
testresult = 1;
err:
EVP_MD_meth_free(md);
EVP_CIPHER_meth_free(ciph);
return testresult;
}
@@ -6110,90 +6108,6 @@ err:
return testresult;
}
typedef struct {
int data;
} custom_ciph_ctx;
static int custom_ciph_init_called = 0;
static int custom_ciph_cleanup_called = 0;
static int custom_ciph_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc)
{
custom_ciph_ctx *p = EVP_CIPHER_CTX_get_cipher_data(ctx);
if (p == NULL)
return 0;
custom_ciph_init_called++;
return 1;
}
static int custom_ciph_cleanup(EVP_CIPHER_CTX *ctx)
{
custom_ciph_ctx *p = EVP_CIPHER_CTX_get_cipher_data(ctx);
if (p == NULL)
/* Nothing to do */
return 1;
custom_ciph_cleanup_called++;
return 1;
}
static int test_custom_ciph_meth(void)
{
EVP_CIPHER_CTX *ciphctx = NULL;
EVP_CIPHER *tmp = NULL;
int testresult = 0;
int nid;
/*
* We are testing deprecated functions. We don't support a non-default
* library context in this test.
*/
if (testctx != NULL)
return TEST_skip("Non-default libctx");
custom_ciph_init_called = custom_ciph_cleanup_called = 0;
nid = OBJ_create("1.3.6.1.4.1.16604.998866.2", "custom-ciph", "custom-ciph");
if (!TEST_int_ne(nid, NID_undef))
goto err;
if (!TEST_int_eq(OBJ_txt2nid("1.3.6.1.4.1.16604.998866.2"), nid))
goto err;
tmp = EVP_CIPHER_meth_new(nid, 16, 16);
if (!TEST_ptr(tmp))
goto err;
if (!TEST_true(EVP_CIPHER_meth_set_init(tmp, custom_ciph_init))
|| !TEST_true(EVP_CIPHER_meth_set_flags(tmp, EVP_CIPH_ALWAYS_CALL_INIT))
|| !TEST_true(EVP_CIPHER_meth_set_cleanup(tmp, custom_ciph_cleanup))
|| !TEST_true(EVP_CIPHER_meth_set_impl_ctx_size(tmp,
sizeof(custom_ciph_ctx))))
goto err;
ciphctx = EVP_CIPHER_CTX_new();
if (!TEST_ptr(ciphctx)
/*
* Initing our custom cipher and then initing another cipher
* should result in the init and cleanup functions of the custom
* cipher being called.
*/
|| !TEST_true(EVP_CipherInit_ex(ciphctx, tmp, NULL, NULL, NULL, 1))
|| !TEST_true(EVP_CipherInit_ex(ciphctx, EVP_aes_128_cbc(), NULL,
NULL, NULL, 1))
|| !TEST_int_eq(custom_ciph_init_called, 1)
|| !TEST_int_eq(custom_ciph_cleanup_called, 1))
goto err;
testresult = 1;
err:
EVP_CIPHER_CTX_free(ciphctx);
EVP_CIPHER_meth_free(tmp);
return testresult;
}
#endif /* OPENSSL_NO_DEPRECATED_3_0 */
#ifndef OPENSSL_NO_ECX
@@ -7016,9 +6930,8 @@ int setup_tests(void)
#ifndef OPENSSL_NO_DEPRECATED_3_0
ADD_ALL_TESTS(test_custom_pmeth, 12);
ADD_TEST(test_evp_md_cipher_meth);
ADD_TEST(test_evp_md_meth);
ADD_TEST(test_custom_md_meth);
ADD_TEST(test_custom_ciph_meth);
#endif
#ifndef OPENSSL_NO_ECX

View File

@@ -850,24 +850,6 @@ EVP_MD_meth_get_final ? 4_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0
EVP_MD_meth_get_copy ? 4_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0
EVP_MD_meth_get_cleanup ? 4_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0
EVP_MD_meth_get_ctrl ? 4_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0
EVP_CIPHER_meth_new ? 4_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0
EVP_CIPHER_meth_dup ? 4_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0
EVP_CIPHER_meth_free ? 4_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0
EVP_CIPHER_meth_set_iv_length ? 4_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0
EVP_CIPHER_meth_set_flags ? 4_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0
EVP_CIPHER_meth_set_impl_ctx_size ? 4_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0
EVP_CIPHER_meth_set_init ? 4_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0
EVP_CIPHER_meth_set_do_cipher ? 4_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0
EVP_CIPHER_meth_set_cleanup ? 4_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0
EVP_CIPHER_meth_set_set_asn1_params ? 4_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0
EVP_CIPHER_meth_set_get_asn1_params ? 4_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0
EVP_CIPHER_meth_set_ctrl ? 4_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0
EVP_CIPHER_meth_get_init ? 4_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0
EVP_CIPHER_meth_get_do_cipher ? 4_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0
EVP_CIPHER_meth_get_cleanup ? 4_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0
EVP_CIPHER_meth_get_set_asn1_params ? 4_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0
EVP_CIPHER_meth_get_get_asn1_params ? 4_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0
EVP_CIPHER_meth_get_ctrl ? 4_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0
EVP_MD_get_type ? 4_0_0 EXIST::FUNCTION:
EVP_MD_get0_name ? 4_0_0 EXIST::FUNCTION:
EVP_MD_get0_description ? 4_0_0 EXIST::FUNCTION: