commit 395270ce1d547ba857f704533890c7e915c52cb7
Author: Alok Menghrajani <alok@squareup.com>
Date:   Mon Sep 8 14:40:43 2014 -0700

    Ensures that EVP encryption & decryption operations check the encrypt flag on the context.
    
    This change ensures that a user cannot accidentally decrypt data with an encryption context
    or vice-versa. Without the check, if an encryption context is used to decrypt
    EVP_aes_256_gcm encrypted data, the code will fail to validate the TAG.
    
    Example code availabe at: http://quaxio.com/wtf/openssl_wtf.html

diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c
index f705967..d690ca1 100644
--- a/crypto/evp/evp_enc.c
+++ b/crypto/evp/evp_enc.c
@@ -295,7 +295,7 @@ int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *im
 	return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 0);
 	}
 
-int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
+int EVP_EncryptOrDecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
 	     const unsigned char *in, int inl)
 	{
 	int i,j,bl;
@@ -368,6 +368,17 @@ 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)
+	{
+
+	if (!ctx->encrypt) {
+		// Disallow using a decryption context for encryption
+		return 0;
+	}
+	return EVP_EncryptOrDecryptUpdate(ctx, out, outl, in, inl);
+	}
+
 int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
 	{
 	int ret;
@@ -380,6 +391,11 @@ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
 	int n,ret;
 	unsigned int i, b, bl;
 
+	if (!ctx->encrypt) {
+		// Disallow using a decryption context for encryption
+		return 0;
+	}
+
 	if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER)
 		{
 		ret = ctx->cipher->do_cipher(ctx, out, NULL, 0);
@@ -427,6 +443,11 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
 	int fix_len;
 	unsigned int b;
 
+	if (ctx->encrypt) {
+		// Disallow using an encryption context for decryption
+		return 0;
+	}
+
 	if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER)
 		{
 		fix_len = ctx->cipher->do_cipher(ctx, out, in, inl);
@@ -447,7 +468,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_EncryptOrDecryptUpdate(ctx, out, outl, in, inl);
 
 	b=ctx->cipher->block_size;
 	OPENSSL_assert(b <= sizeof ctx->final);
@@ -462,7 +483,7 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
 		fix_len = 0;
 
 
-	if(!EVP_EncryptUpdate(ctx,out,outl,in,inl))
+	if(!EVP_EncryptOrDecryptUpdate(ctx,out,outl,in,inl))
 		return 0;
 
 	/* if we have 'decrypted' a multiple of block size, make sure
@@ -495,6 +516,11 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
 	unsigned int b;
 	*outl=0;
 
+	if (ctx->encrypt) {
+		// Disallow using an encryption context for decryption
+		return 0;
+	}
+
 	if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER)
 		{
 		i = ctx->cipher->do_cipher(ctx, out, NULL, 0);
