Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add appropriate NULL checks in EVP_CIPHER api #22995

Closed
wants to merge 10 commits into from
10 changes: 9 additions & 1 deletion apps/enc.c
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,9 @@ int enc_main(int argc, char **argv)
/* not needed if HASH_UPDATE() is fixed : */
int islen = (sptr != NULL ? saltlen : 0);

if (ivlen < 0)
goto end;

if (!PKCS5_PBKDF2_HMAC(str, str_len, sptr, islen,
iter, dgst, iklen+ivlen, tmpkeyiv)) {
BIO_printf(bio_err, "PKCS5_PBKDF2_HMAC failed\n");
Expand Down Expand Up @@ -593,6 +596,11 @@ int enc_main(int argc, char **argv)
}
if (hiv != NULL) {
int siz = EVP_CIPHER_get_iv_length(cipher);

if (siz < 0) {
BIO_printf(bio_err, "warning, cipher not initalized\n");
goto end;
}
if (siz == 0) {
BIO_printf(bio_err, "warning: iv not used by this cipher\n");
} else if (!set_hex(hiv, iv, siz)) {
Expand All @@ -601,7 +609,7 @@ int enc_main(int argc, char **argv)
}
}
if ((hiv == NULL) && (str == NULL)
&& EVP_CIPHER_get_iv_length(cipher) != 0
&& EVP_CIPHER_get_iv_length(cipher) <= 0
&& wrap == 0) {
/*
* No IV was explicitly set and no IV was generated.
Expand Down
2 changes: 1 addition & 1 deletion crypto/asn1/p5_scrypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ X509_ALGOR *PKCS5_pbe2_set_scrypt(const EVP_CIPHER *cipher,
}

/* Create random IV */
if (EVP_CIPHER_get_iv_length(cipher)) {
if (EVP_CIPHER_get_iv_length(cipher) > 0) {
if (aiv)
memcpy(iv, aiv, EVP_CIPHER_get_iv_length(cipher));
else if (RAND_bytes(iv, EVP_CIPHER_get_iv_length(cipher)) <= 0)
Expand Down
12 changes: 8 additions & 4 deletions crypto/cmac/cmac.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ int CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in)

if (in->nlast_block == -1)
return 0;
if ((bl = EVP_CIPHER_CTX_get_block_size(in->cctx)) < 0)
if ((bl = EVP_CIPHER_CTX_get_block_size(in->cctx)) == 0)
return 0;
if (!EVP_CIPHER_CTX_copy(out->cctx, in->cctx))
return 0;
Expand All @@ -111,6 +111,7 @@ int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen,
const EVP_CIPHER *cipher, ENGINE *impl)
{
static const unsigned char zero_iv[EVP_MAX_BLOCK_LENGTH] = { 0 };
int block_len;

/* All zeros means restart */
if (!key && !cipher && !impl && keylen == 0) {
Expand All @@ -119,7 +120,10 @@ int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen,
return 0;
if (!EVP_EncryptInit_ex(ctx->cctx, NULL, NULL, NULL, zero_iv))
return 0;
memset(ctx->tbl, 0, EVP_CIPHER_CTX_get_block_size(ctx->cctx));
block_len = EVP_CIPHER_CTX_get_block_size(ctx->cctx);
if (block_len == 0)
return 0;
memset(ctx->tbl, 0, block_len);
ctx->nlast_block = 0;
return 1;
}
Expand Down Expand Up @@ -170,7 +174,7 @@ int CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen)
return 0;
if (dlen == 0)
return 1;
if ((bl = EVP_CIPHER_CTX_get_block_size(ctx->cctx)) < 0)
if ((bl = EVP_CIPHER_CTX_get_block_size(ctx->cctx)) == 0)
return 0;
/* Copy into partial block if we need to */
if (ctx->nlast_block > 0) {
Expand Down Expand Up @@ -234,7 +238,7 @@ int CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen)

if (ctx->nlast_block == -1)
return 0;
if ((bl = EVP_CIPHER_CTX_get_block_size(ctx->cctx)) < 0)
if ((bl = EVP_CIPHER_CTX_get_block_size(ctx->cctx)) == 0)
return 0;
if (poutlen != NULL)
*poutlen = (size_t)bl;
Expand Down
8 changes: 8 additions & 0 deletions crypto/cms/cms_pwri.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,10 @@ static int kek_unwrap_key(unsigned char *out, size_t *outlen,
size_t blocklen = EVP_CIPHER_CTX_get_block_size(ctx);
unsigned char *tmp;
int outl, rv = 0;

if (blocklen == 0)
return 0;

if (inlen < 2 * blocklen) {
/* too small */
return 0;
Expand Down Expand Up @@ -257,6 +261,10 @@ static int kek_wrap_key(unsigned char *out, size_t *outlen,
size_t blocklen = EVP_CIPHER_CTX_get_block_size(ctx);
size_t olen;
int dummy;

if (blocklen == 0)
return 0;

/*
* First decide length of output buffer: need header and round up to
* multiple of block length.
Expand Down
3 changes: 3 additions & 0 deletions crypto/crmf/crmf_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,9 @@ X509
ecert->encSymmKey->length) <= 0)
goto end;

if (EVP_CIPHER_get_iv_length(cipher) < 0)
goto end;

if ((iv = OPENSSL_malloc(EVP_CIPHER_get_iv_length(cipher))) == NULL)
goto end;
if (ASN1_TYPE_get_octetstring(ecert->symmAlg->parameter, iv,
Expand Down
4 changes: 4 additions & 0 deletions crypto/evp/bio_enc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
12 changes: 12 additions & 0 deletions crypto/evp/e_aes.c
Original file line number Diff line number Diff line change
Expand Up @@ -1081,6 +1081,9 @@ static int s390x_aes_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
int n = cctx->res;
int rem;

if (ivlen < 0)
return 0;

memcpy(cctx->kmo.param.cv, iv, ivlen);
while (n && len) {
*out = *in ^ cctx->kmo.param.cv[n];
Expand Down Expand Up @@ -1235,6 +1238,9 @@ static int s390x_aes_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const int ivlen = EVP_CIPHER_CTX_get_iv_length(ctx);
unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);

if (ivlen < 0)
return 0;

memcpy(cctx->kmf.param.cv, iv, ivlen);
s390x_kmf(in, len, out, cctx->fc, &cctx->kmf.param);
memcpy(iv, cctx->kmf.param.cv, ivlen);
Expand Down Expand Up @@ -1450,6 +1456,8 @@ static int s390x_aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
switch (type) {
case EVP_CTRL_INIT:
ivlen = EVP_CIPHER_get_iv_length(c->cipher);
if (ivlen < 0)
return 0;
gctx->key_set = 0;
gctx->iv_set = 0;
gctx->ivlen = ivlen;
Expand Down Expand Up @@ -2658,6 +2666,8 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
EVP_AES_GCM_CTX *gctx = EVP_C_DATA(EVP_AES_GCM_CTX,c);
switch (type) {
case EVP_CTRL_INIT:
if (EVP_CIPHER_get_iv_length(c->cipher) < 0)
return 0;
gctx->key_set = 0;
gctx->iv_set = 0;
gctx->ivlen = EVP_CIPHER_get_iv_length(c->cipher);
Expand Down Expand Up @@ -3858,6 +3868,8 @@ static int aes_ocb_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)

switch (type) {
case EVP_CTRL_INIT:
if (EVP_CIPHER_get_iv_length(c->cipher) < 0)
return 0;
octx->key_set = 0;
octx->iv_set = 0;
octx->ivlen = EVP_CIPHER_get_iv_length(c->cipher);
Expand Down
2 changes: 2 additions & 0 deletions crypto/evp/e_aria.c
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,8 @@ static int aria_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)

switch (type) {
case EVP_CTRL_INIT:
if (EVP_CIPHER_get_iv_length(c->cipher) < 0)
return 0;
gctx->key_set = 0;
gctx->iv_set = 0;
gctx->ivlen = EVP_CIPHER_get_iv_length(c->cipher);
Expand Down
3 changes: 2 additions & 1 deletion crypto/evp/e_rc2.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,8 @@ static int rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
if (type != NULL) {
num = rc2_meth_to_magic(c);
j = EVP_CIPHER_CTX_get_iv_length(c);
i = ASN1_TYPE_set_int_octetstring(type, num, c->oiv, j);
if (j >= 0)
i = ASN1_TYPE_set_int_octetstring(type, num, c->oiv, j);
}
return i;
}
Expand Down
5 changes: 5 additions & 0 deletions crypto/evp/evp_enc.c
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,11 @@ static int evp_cipher_init_internal(EVP_CIPHER_CTX *ctx,
return 0;
}

if (EVP_CIPHER_CTX_get_iv_length(ctx) < 0) {
ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_IV_LENGTH);
return 0;
}

return ctx->cipher->einit(ctx->algctx,
key,
key == NULL ? 0
Expand Down
2 changes: 1 addition & 1 deletion crypto/evp/evp_key.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
37 changes: 28 additions & 9 deletions crypto/evp/evp_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,15 @@ int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *ctx, ASN1_TYPE *type)
{
int i = 0;
unsigned int l;
int l;

if (type != NULL) {
unsigned char iv[EVP_MAX_IV_LENGTH];

l = EVP_CIPHER_CTX_get_iv_length(ctx);
if (!ossl_assert(l <= sizeof(iv)))
if (l < 0)
return -1;
if (!ossl_assert((long unsigned int)l <= sizeof(iv)))
nhorman marked this conversation as resolved.
Show resolved Hide resolved
return -1;
i = ASN1_TYPE_get_octetstring(type, iv, l);
if (i != (int)l)
Expand Down Expand Up @@ -81,8 +83,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)
return -1;
nhorman marked this conversation as resolved.
Show resolved Hide resolved

cipher = c->cipher;
/*
* For legacy implementations, we detect custom AlgorithmIdentifier
* parameter handling by checking if the function pointer
Expand Down Expand Up @@ -172,8 +178,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)
return -1;
nhorman marked this conversation as resolved.
Show resolved Hide resolved

cipher = c->cipher;
/*
* For legacy implementations, we detect custom AlgorithmIdentifier
* parameter handling by checking if there the function pointer
Expand Down Expand Up @@ -387,7 +397,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)
Expand All @@ -403,6 +413,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,
Expand All @@ -415,6 +428,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),
Expand Down Expand Up @@ -454,7 +470,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))
Expand Down Expand Up @@ -499,7 +515,7 @@ 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) ? -1 : cipher->iv_len;
nhorman marked this conversation as resolved.
Show resolved Hide resolved
}

int EVP_CIPHER_CTX_get_iv_length(const EVP_CIPHER_CTX *ctx)
Expand All @@ -509,6 +525,9 @@ int EVP_CIPHER_CTX_get_iv_length(const EVP_CIPHER_CTX *ctx)
size_t v = len;
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };

if (len == -1)
return -1;

if (ctx->cipher->get_ctx_params != NULL) {
params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_IVLEN,
&v);
Expand Down Expand Up @@ -678,12 +697,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)
Expand Down
6 changes: 6 additions & 0 deletions crypto/pem/pem_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ int PEM_X509_INFO_write_bio(BIO *bp, const X509_INFO *xi, EVP_CIPHER *enc,
if (enc != NULL) {
objstr = EVP_CIPHER_get0_name(enc);
if (objstr == NULL
|| EVP_CIPHER_get_iv_length(enc) < 0
/*
* Check "Proc-Type: 4,Encrypted\nDEK-Info: objstr,hex-iv\n"
* fits into buf
Expand Down Expand Up @@ -273,6 +274,11 @@ int PEM_X509_INFO_write_bio(BIO *bp, const X509_INFO *xi, EVP_CIPHER *enc,
goto err;
}

if (EVP_CIPHER_get_iv_length(enc) < 0) {
nhorman marked this conversation as resolved.
Show resolved Hide resolved
ERR_raise(ERR_LIB_PEM, PEM_R_CIPHER_IS_NULL);
goto err;
}

/* Create the right magic header stuff */
buf[0] = '\0';
PEM_proc_type(buf, PEM_TYPE_ENCRYPTED);
Expand Down
6 changes: 5 additions & 1 deletion crypto/pem/pem_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp,

if (enc != NULL) {
objstr = EVP_CIPHER_get0_name(enc);
if (objstr == NULL || EVP_CIPHER_get_iv_length(enc) == 0
if (objstr == NULL || EVP_CIPHER_get_iv_length(enc) <= 0
nhorman marked this conversation as resolved.
Show resolved Hide resolved
nhorman marked this conversation as resolved.
Show resolved Hide resolved
|| EVP_CIPHER_get_iv_length(enc) > (int)sizeof(iv)
/*
* Check "Proc-Type: 4,Encrypted\nDEK-Info: objstr,hex-iv\n"
Expand Down Expand Up @@ -552,6 +552,10 @@ int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher)
return 0;
}
ivlen = EVP_CIPHER_get_iv_length(enc);
if (ivlen < 0) {
nhorman marked this conversation as resolved.
Show resolved Hide resolved
ERR_raise(ERR_LIB_PEM, PEM_R_CIPHER_IS_NULL);
return 0;
}
nhorman marked this conversation as resolved.
Show resolved Hide resolved
if (ivlen > 0 && *header++ != ',') {
ERR_raise(ERR_LIB_PEM, PEM_R_MISSING_DEK_IV);
return 0;
Expand Down
8 changes: 7 additions & 1 deletion crypto/pkcs12/p12_decr.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ unsigned char *PKCS12_pbe_crypt_ex(const X509_ALGOR *algor,
int outlen, i;
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
int max_out_len, mac_len = 0;
int block_size;

if (ctx == NULL) {
ERR_raise(ERR_LIB_PKCS12, ERR_R_EVP_LIB);
Expand All @@ -43,7 +44,12 @@ unsigned char *PKCS12_pbe_crypt_ex(const X509_ALGOR *algor,
* It's appended to encrypted text on encrypting
* MAC should be processed on decrypting separately from plain text
*/
max_out_len = inlen + EVP_CIPHER_CTX_get_block_size(ctx);
block_size = EVP_CIPHER_CTX_get_block_size(ctx);

if (block_size == 0)
goto err;
nhorman marked this conversation as resolved.
Show resolved Hide resolved

max_out_len = inlen + block_size;
if ((EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(ctx))
& EVP_CIPH_FLAG_CIPHER_WITH_MAC) != 0) {
if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD, 0, &mac_len) < 0) {
Expand Down