From a8bf2f8f24bda57c860e4356f31264fff63fe8b9 Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Sun, 9 Dec 2018 14:18:50 +0100 Subject: [PATCH] Prevent calling decryption in an encryption context and vice versa Reviewed-by: Kurt Roeckx Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/7852) --- crypto/evp/evp_enc.c | 45 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c index d05c1f744f..7fdf7598d2 100644 --- a/crypto/evp/evp_enc.c +++ b/crypto/evp/evp_enc.c @@ -294,8 +294,9 @@ int is_partially_overlapping(const void *ptr1, const void *ptr2, int len) return overlapped; } -int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, - const unsigned char *in, int inl) +static int evp_EncryptDecryptUpdate(EVP_CIPHER_CTX *ctx, + unsigned char *out, int *outl, + const unsigned char *in, int inl) { int i, j, bl, cmpl = inl; @@ -307,7 +308,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, 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)) { - EVPerr(EVP_F_EVP_ENCRYPTUPDATE, EVP_R_PARTIALLY_OVERLAPPING); + EVPerr(EVP_F_EVP_ENCRYPTDECRYPTUPDATE, EVP_R_PARTIALLY_OVERLAPPING); return 0; } @@ -324,7 +325,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, return inl == 0; } if (is_partially_overlapping(out + ctx->buf_len, in, cmpl)) { - EVPerr(EVP_F_EVP_ENCRYPTUPDATE, EVP_R_PARTIALLY_OVERLAPPING); + EVPerr(EVP_F_EVP_ENCRYPTDECRYPTUPDATE, EVP_R_PARTIALLY_OVERLAPPING); return 0; } @@ -371,6 +372,19 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, return 1; } + +int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl) +{ + /* Prevent accidental use of decryption context when encrypting */ + if (!ctx->encrypt) { + EVPerr(EVP_F_EVP_ENCRYPTUPDATE, EVP_R_INVALID_OPERATION); + return 0; + } + + return evp_EncryptDecryptUpdate(ctx, out, outl, in, inl); +} + int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) { int ret; @@ -383,6 +397,12 @@ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) int n, ret; unsigned int i, b, bl; + /* Prevent accidental use of decryption context when encrypting */ + if (!ctx->encrypt) { + EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX, EVP_R_INVALID_OPERATION); + return 0; + } + if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { ret = ctx->cipher->do_cipher(ctx, out, NULL, 0); if (ret < 0) @@ -426,6 +446,12 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, int fix_len, cmpl = inl; unsigned int b; + /* Prevent accidental use of encryption context when decrypting */ + if (ctx->encrypt) { + EVPerr(EVP_F_EVP_DECRYPTUPDATE, EVP_R_INVALID_OPERATION); + return 0; + } + b = ctx->cipher->block_size; if (EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS)) @@ -452,7 +478,7 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, } if (ctx->flags & EVP_CIPH_NO_PADDING) - return EVP_EncryptUpdate(ctx, out, outl, in, inl); + return evp_EncryptDecryptUpdate(ctx, out, outl, in, inl); OPENSSL_assert(b <= sizeof(ctx->final)); @@ -469,7 +495,7 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, } else fix_len = 0; - if (!EVP_EncryptUpdate(ctx, out, outl, in, inl)) + if (!evp_EncryptDecryptUpdate(ctx, out, outl, in, inl)) return 0; /* @@ -500,6 +526,13 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) { int i, n; unsigned int b; + + /* Prevent accidental use of encryption context when decrypting */ + if (ctx->encrypt) { + EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_INVALID_OPERATION); + return 0; + } + *outl = 0; if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {