Skip to content

Commit

Permalink
evp: process key length and iv length early if present
Browse files Browse the repository at this point in the history
evp_cipher_init_internal() takes a params array argument and this is processed
late in the initialisation process for some ciphers (AEAD ones).

This means that changing the IV length as a parameter will either truncate the
IV (very bad if SP 800-38d section 8.2.1 is used) or grab extra uninitialised
bytes.

Truncation is very bad if SP 800-38d section 8.2.1 is being used to
contruct a deterministic IV.  This leads to an instant loss of confidentiality.

Grabbing extra bytes isn't so serious, it will most likely result in a bad
decryption.

Problem reported by Tony Battersby of Cybernetics.com but earlier discovered
and raised as issue #19822.

Fixes CVE-2023-5363
Fixes #19822

Reviewed-by: Hugo Landau <hlandau@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(cherry picked from commit 5f69f5c)
  • Loading branch information
paulidale authored and mattcaswell committed Oct 24, 2023
1 parent 23d2135 commit 0df4063
Showing 1 changed file with 36 additions and 0 deletions.
36 changes: 36 additions & 0 deletions crypto/evp/evp_enc.c
Expand Up @@ -223,6 +223,42 @@ static int evp_cipher_init_internal(EVP_CIPHER_CTX *ctx,
return 0;
}

#ifndef FIPS_MODULE
/*
* Fix for CVE-2023-5363
* Passing in a size as part of the init call takes effect late
* so, force such to occur before the initialisation.
*
* The FIPS provider's internal library context is used in a manner
* such that this is not an issue.
*/
if (params != NULL) {
OSSL_PARAM param_lens[3] = { OSSL_PARAM_END, OSSL_PARAM_END,
OSSL_PARAM_END };
OSSL_PARAM *q = param_lens;
const OSSL_PARAM *p;

p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN);
if (p != NULL)
memcpy(q++, p, sizeof(*q));

/*
* Note that OSSL_CIPHER_PARAM_AEAD_IVLEN is a synomym for
* OSSL_CIPHER_PARAM_IVLEN so both are covered here.
*/
p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_IVLEN);
if (p != NULL)
memcpy(q++, p, sizeof(*q));

if (q != param_lens) {
if (!EVP_CIPHER_CTX_set_params(ctx, param_lens)) {
ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_LENGTH);
return 0;
}
}
}
#endif

if (enc) {
if (ctx->cipher->einit == NULL) {
ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
Expand Down

0 comments on commit 0df4063

Please sign in to comment.