Main Content

Inconsistent cipher operations

You perform encryption and decryption steps in succession with the same cipher context without a reinitialization in between

Description

This defect occurs when you perform an encryption and decryption step with the same cipher context. You do not reinitialize the context in between those steps. The checker applies to symmetric encryption only.

For instance, you set up a cipher context for decryption using EVP_DecryptInit_ex.

EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv);
However, you use the context for encryption using EVP_EncryptUpdate.
EVP_EncryptUpdate(ctx, out_buf, &out_len, src, len); 

Risk

Mixing up encryption and decryption steps can lead to obscure code. It is difficult to determine at a glance whether the current cipher context is used for encryption or decryption. The mixup can also lead to race conditions, failed encryption, and unexpected ciphertext.

Fix

After you set up a cipher context for a certain family of operations, use the context for only that family of operations.

For instance, if you set up a cipher context for decryption using EVP_DecryptInit_ex, use the context afterward for decryption only.

Examples

expand all



#include <openssl/evp.h>
#include <stdlib.h>

/* Using the cryptographic routines */

unsigned char *out_buf;
int out_len;
unsigned char g_key[16];
unsigned char g_iv[16];
void func(unsigned char* src, int len) {
    
    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
    EVP_CIPHER_CTX_init(ctx);
    
    /* Cipher context set up for decryption*/
    EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, g_key, g_iv);

    /* Update step for encryption */
    EVP_EncryptUpdate(ctx, out_buf, &out_len, src, len);        
}

In this example, the cipher context ctx is set up for decryption using EVP_DecryptInit_ex. However, immediately afterward, the context is used for encryption using EVP_EncryptUpdate.

Correction — Change Setup Step

One possible correction is to change the setup step. If you want to use the cipher context for encryption, set it up using EVP_EncryptInit_ex.


#include <openssl/evp.h>
#include <stdlib.h>

unsigned char *out_buf;
int out_len;
unsigned char g_key[16];
unsigned char g_iv[16];

void func(unsigned char* src, int len) {
    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
    EVP_CIPHER_CTX_init(ctx);

    /* Cipher context set up for encryption*/
    EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, g_key, g_iv);

    /* Update step for encryption */
    EVP_EncryptUpdate(ctx, out_buf, &out_len, src, len);        
}

Result Information

Group: Cryptography
Language: C | C++
Default: Off
Command-Line Syntax: CRYPTO_CIPHER_BAD_FUNCTION
Impact: Medium

Version History

Introduced in R2017a