summaryrefslogtreecommitdiffstats
path: root/crypto/evp
diff options
context:
space:
mode:
authorNeil Horman <nhorman@openssl.org>2023-12-09 13:40:01 -0500
committerNeil Horman <nhorman@openssl.org>2024-01-25 08:27:53 -0500
commit6f22bcd631ab622c2436bc5b299ba2677c388375 (patch)
treee62244a2a0e8f491ab3e3b582928dbc6383f7abf /crypto/evp
parentff78d94b131d7bb3b761509d3ce0dd864b1420e3 (diff)
Add appropriate NULL checks in EVP_CIPHER api
The EVP_CIPHER api currently assumes that calls made into several APIs have already initalized the cipher in a given context via a call to EVP_CipherInit[_ex[2]]. If that hasnt been done, instead of an error, the result is typically a SIGSEGV. Correct that by adding missing NULL checks in the apropriate apis prior to using ctx->cipher Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/22995)
Diffstat (limited to 'crypto/evp')
-rw-r--r--crypto/evp/bio_enc.c4
-rw-r--r--crypto/evp/evp_key.c2
-rw-r--r--crypto/evp/evp_lib.c34
3 files changed, 31 insertions, 9 deletions
diff --git a/crypto/evp/bio_enc.c b/crypto/evp/bio_enc.c
index ece3f6d57f..fc6eec7764 100644
--- a/crypto/evp/bio_enc.c
+++ b/crypto/evp/bio_enc.c
@@ -132,6 +132,10 @@ static int enc_read(BIO *b, char *out, int outl)
}
blocksize = EVP_CIPHER_CTX_get_block_size(ctx->cipher);
+
+ if (blocksize == 0)
+ return 0;
+
if (blocksize == 1)
blocksize = 0;
diff --git a/crypto/evp/evp_key.c b/crypto/evp/evp_key.c
index 607d45ee23..a4ba76cd83 100644
--- a/crypto/evp/evp_key.c
+++ b/crypto/evp/evp_key.c
@@ -88,7 +88,7 @@ int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md,
nkey = EVP_CIPHER_get_key_length(type);
niv = EVP_CIPHER_get_iv_length(type);
OPENSSL_assert(nkey <= EVP_MAX_KEY_LENGTH);
- OPENSSL_assert(niv <= EVP_MAX_IV_LENGTH);
+ OPENSSL_assert(niv >= 0 && niv <= EVP_MAX_IV_LENGTH);
if (data == NULL)
return nkey;
diff --git a/crypto/evp/evp_lib.c b/crypto/evp/evp_lib.c
index f29d592e0f..e539a76a78 100644
--- a/crypto/evp/evp_lib.c
+++ b/crypto/evp/evp_lib.c
@@ -81,8 +81,12 @@ int evp_cipher_param_to_asn1_ex(EVP_CIPHER_CTX *c, ASN1_TYPE *type,
evp_cipher_aead_asn1_params *asn1_params)
{
int ret = -1; /* Assume the worst */
- const EVP_CIPHER *cipher = c->cipher;
+ const EVP_CIPHER *cipher;
+ if (c == NULL || c->cipher == NULL)
+ goto err;
+
+ cipher = c->cipher;
/*
* For legacy implementations, we detect custom AlgorithmIdentifier
* parameter handling by checking if the function pointer
@@ -172,8 +176,12 @@ int evp_cipher_asn1_to_param_ex(EVP_CIPHER_CTX *c, ASN1_TYPE *type,
evp_cipher_aead_asn1_params *asn1_params)
{
int ret = -1; /* Assume the worst */
- const EVP_CIPHER *cipher = c->cipher;
+ const EVP_CIPHER *cipher;
+
+ if (c == NULL || c->cipher == NULL)
+ goto err;
+ cipher = c->cipher;
/*
* For legacy implementations, we detect custom AlgorithmIdentifier
* parameter handling by checking if there the function pointer
@@ -230,6 +238,7 @@ int evp_cipher_asn1_to_param_ex(EVP_CIPHER_CTX *c, ASN1_TYPE *type,
ret = -2;
}
+err:
if (ret == -2)
ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_CIPHER);
else if (ret <= 0)
@@ -387,7 +396,7 @@ int evp_cipher_cache_constants(EVP_CIPHER *cipher)
int EVP_CIPHER_get_block_size(const EVP_CIPHER *cipher)
{
- return cipher->block_size;
+ return (cipher == NULL) ? 0 : cipher->block_size;
}
int EVP_CIPHER_CTX_get_block_size(const EVP_CIPHER_CTX *ctx)
@@ -403,6 +412,9 @@ int EVP_CIPHER_impl_ctx_size(const EVP_CIPHER *e)
int EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, unsigned int inl)
{
+ if (ctx == NULL || ctx->cipher == NULL)
+ return 0;
+
if (ctx->cipher->prov != NULL) {
/*
* If the provided implementation has a ccipher function, we use it,
@@ -415,6 +427,9 @@ int EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
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),
@@ -454,7 +469,7 @@ EVP_CIPHER *EVP_CIPHER_CTX_get1_cipher(EVP_CIPHER_CTX *ctx)
{
EVP_CIPHER *cipher;
- if (ctx == NULL)
+ if (ctx == NULL || ctx->cipher == NULL)
return NULL;
cipher = (EVP_CIPHER *)ctx->cipher;
if (!EVP_CIPHER_up_ref(cipher))
@@ -469,7 +484,7 @@ int EVP_CIPHER_CTX_is_encrypting(const EVP_CIPHER_CTX *ctx)
unsigned long EVP_CIPHER_get_flags(const EVP_CIPHER *cipher)
{
- return cipher->flags;
+ return cipher == NULL ? 0 : cipher->flags;
}
void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx)
@@ -499,11 +514,14 @@ void *EVP_CIPHER_CTX_set_cipher_data(EVP_CIPHER_CTX *ctx, void *cipher_data)
int EVP_CIPHER_get_iv_length(const EVP_CIPHER *cipher)
{
- return cipher->iv_len;
+ return (cipher == NULL) ? 0 : cipher->iv_len;
}
int EVP_CIPHER_CTX_get_iv_length(const EVP_CIPHER_CTX *ctx)
{
+ if (ctx->cipher == NULL)
+ return 0;
+
if (ctx->iv_len < 0) {
int rv, len = EVP_CIPHER_get_iv_length(ctx->cipher);
size_t v = len;
@@ -678,12 +696,12 @@ int EVP_CIPHER_CTX_get_key_length(const EVP_CIPHER_CTX *ctx)
int EVP_CIPHER_get_nid(const EVP_CIPHER *cipher)
{
- return cipher->nid;
+ return (cipher == NULL) ? NID_undef : cipher->nid;
}
int EVP_CIPHER_CTX_get_nid(const EVP_CIPHER_CTX *ctx)
{
- return ctx->cipher->nid;
+ return EVP_CIPHER_get_nid(ctx->cipher);
}
int EVP_CIPHER_is_a(const EVP_CIPHER *cipher, const char *name)