summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2018-12-10 10:18:10 +0100
committerRichard Levitte <levitte@openssl.org>2019-01-15 18:32:36 +0100
commitcfa9a7cd5316fddd2e41bda3f3a1e50537e784bb (patch)
treea0b5bc758b4e70a64d45457464b37595c4a3e41e
parenteed51aa8270dd3feb1fce049aeae505cbfe806f5 (diff)
Prevent calling decryption in an encryption context and vice versa
Reviewed-by: Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com> (Merged from https://github.com/openssl/openssl/pull/7856)
-rw-r--r--crypto/evp/evp_enc.c40
1 files changed, 36 insertions, 4 deletions
diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c
index 0c740d1679..c63fb53ac8 100644
--- a/crypto/evp/evp_enc.c
+++ b/crypto/evp/evp_enc.c
@@ -317,8 +317,9 @@ int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 0);
}
-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;
@@ -380,6 +381,18 @@ 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;
@@ -392,6 +405,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 = M_do_cipher(ctx, out, NULL, 0);
if (ret < 0)
@@ -435,6 +454,12 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
int fix_len;
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;
+ }
+
if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
fix_len = M_do_cipher(ctx, out, in, inl);
if (fix_len < 0) {
@@ -451,7 +476,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);
b = ctx->cipher->block_size;
OPENSSL_assert(b <= sizeof(ctx->final));
@@ -463,7 +488,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;
/*
@@ -494,6 +519,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) {