EVP_*Update: ensure that input NULL with length 0 isn't passed
Even with custom ciphers, the combination in == NULL && inl == 0 should not be passed down to the backend cipher function. The reason is that these are the values passed by EVP_*Final, and some of the backend cipher functions do check for these to see if a "final" call is made. An exception is made for CCM mode which has special handling for the case where inl == 0: this may mean the total plaintext or ciphertext length is 0. This is based on an original commit by Richard Levitte. Fixes #8675 Reviewed-by: Richard Levitte <levitte@openssl.org> (Merged from https://github.com/openssl/openssl/pull/9057)
This commit is contained in:
parent
aeb8d94b6b
commit
420cb707b8
1 changed files with 22 additions and 9 deletions
|
@ -305,6 +305,17 @@ static int evp_EncryptDecryptUpdate(EVP_CIPHER_CTX *ctx,
|
|||
|
||||
bl = ctx->cipher->block_size;
|
||||
|
||||
/*
|
||||
* CCM mode needs to know about the case where inl == 0 && in == NULL - it
|
||||
* means the plaintext/ciphertext length is 0
|
||||
*/
|
||||
if (inl < 0
|
||||
|| (inl == 0
|
||||
&& EVP_CIPHER_mode(ctx->cipher) != EVP_CIPH_CCM_MODE)) {
|
||||
*outl = 0;
|
||||
return inl == 0;
|
||||
}
|
||||
|
||||
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 && is_partially_overlapping(out, in, cmpl)) {
|
||||
|
@ -320,10 +331,6 @@ static int evp_EncryptDecryptUpdate(EVP_CIPHER_CTX *ctx,
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (inl <= 0) {
|
||||
*outl = 0;
|
||||
return inl == 0;
|
||||
}
|
||||
if (is_partially_overlapping(out + ctx->buf_len, in, cmpl)) {
|
||||
EVPerr(EVP_F_EVP_ENCRYPTDECRYPTUPDATE, EVP_R_PARTIALLY_OVERLAPPING);
|
||||
return 0;
|
||||
|
@ -457,6 +464,17 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
|
|||
if (EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS))
|
||||
cmpl = (cmpl + 7) / 8;
|
||||
|
||||
/*
|
||||
* CCM mode needs to know about the case where inl == 0 - it means the
|
||||
* plaintext/ciphertext length is 0
|
||||
*/
|
||||
if (inl < 0
|
||||
|| (inl == 0
|
||||
&& EVP_CIPHER_mode(ctx->cipher) != EVP_CIPH_CCM_MODE)) {
|
||||
*outl = 0;
|
||||
return inl == 0;
|
||||
}
|
||||
|
||||
if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
|
||||
if (b == 1 && is_partially_overlapping(out, in, cmpl)) {
|
||||
EVPerr(EVP_F_EVP_DECRYPTUPDATE, EVP_R_PARTIALLY_OVERLAPPING);
|
||||
|
@ -472,11 +490,6 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
|
|||
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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue